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

Oledrion_products   C

Complexity

Total Complexity 61

Size/Duplication

Total Lines 495
Duplicated Lines 12.12 %

Coupling/Cohesion

Components 2
Dependencies 4

Importance

Changes 0
Metric Value
dl 60
loc 495
rs 6.018
c 0
b 0
f 0
wmc 61
lcom 2
cbo 4

27 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 56 1
B isProductVisible() 5 21 9
A getPictureUrl() 8 8 2
A getPicturePath() 0 8 2
A getThumbUrl() 0 8 2
A getThumbPath() 0 8 2
A pictureExists() 11 11 3
A thumbExists() 11 11 3
A deletePicture() 7 7 2
A attachmentExists() 11 11 3
A deleteAttachment() 0 7 2
A deleteThumb() 7 7 2
A deletePictures() 0 5 1
A getDiscountTTC() 0 4 1
A getTTC() 0 4 1
A isRecommended() 0 8 4
A setRecommended() 0 4 1
A unsetRecommended() 0 4 1
A recommendedPicture() 0 8 2
B getLink() 0 23 6
A productAttributesCount() 0 4 1
A getProductMandatoryAttributesCount() 0 4 1
A getProductMandatoryFieldsList() 0 4 1
A getProductsAttributesList() 0 4 1
A getInitialOptionsPrice() 0 4 1
A isNewProduct() 0 9 2
B toArray() 0 66 4

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Oledrion_products often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Oledrion_products, and based on these observations, apply Extract Interface, too.

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 produits mis en vente
22
 */
23
require __DIR__ . '/classheader.php';
24
25
/**
26
 * Class Oledrion_products
27
 */
28
class Oledrion_products 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('product_id', XOBJ_DTYPE_INT, null, false);
40
        $this->initVar('product_cid', XOBJ_DTYPE_INT, null, false);
41
        $this->initVar('product_title', XOBJ_DTYPE_TXTBOX, null, false);
42
        $this->initVar('product_vendor_id', XOBJ_DTYPE_INT, null, false);
43
        $this->initVar('product_sku', XOBJ_DTYPE_TXTBOX, null, false);
44
        $this->initVar('product_extraid', XOBJ_DTYPE_TXTBOX, null, false);
45
        $this->initVar('product_width', XOBJ_DTYPE_TXTBOX, null, false);
46
        $this->initVar('product_length', XOBJ_DTYPE_TXTBOX, null, false);
47
        $this->initVar('product_unitmeasure1', XOBJ_DTYPE_TXTBOX, null, false);
48
        $this->initVar('product_url', XOBJ_DTYPE_TXTBOX, null, false);
49
        $this->initVar('product_url2', XOBJ_DTYPE_TXTBOX, null, false);
50
        $this->initVar('product_url3', XOBJ_DTYPE_TXTBOX, null, false);
51
        $this->initVar('product_image_url', XOBJ_DTYPE_TXTBOX, null, false);
52
        $this->initVar('product_thumb_url', XOBJ_DTYPE_TXTBOX, null, false);
53
        $this->initVar('product_submitter', XOBJ_DTYPE_INT, null, false);
54
        $this->initVar('product_online', XOBJ_DTYPE_INT, null, false);
55
        $this->initVar('product_date', XOBJ_DTYPE_TXTBOX, null, false);
56
        $this->initVar('product_submitted', XOBJ_DTYPE_INT, null, false);
57
        $this->initVar('product_hits', XOBJ_DTYPE_INT, null, false);
58
        $this->initVar('product_rating', XOBJ_DTYPE_INT, null, false);
59
        $this->initVar('product_votes', XOBJ_DTYPE_INT, null, false);
60
        $this->initVar('product_comments', XOBJ_DTYPE_INT, null, false);
61
        $this->initVar('product_price', XOBJ_DTYPE_TXTBOX, null, false);
62
        $this->initVar('product_shipping_price', XOBJ_DTYPE_TXTBOX, null, false);
63
        $this->initVar('product_discount_price', XOBJ_DTYPE_TXTBOX, null, false);
64
        $this->initVar('product_stock', XOBJ_DTYPE_INT, null, false);
65
        $this->initVar('product_alert_stock', XOBJ_DTYPE_INT, null, false);
66
        $this->initVar('product_summary', XOBJ_DTYPE_TXTAREA, null, false);
67
        $this->initVar('product_description', XOBJ_DTYPE_TXTAREA, null, false);
68
        $this->initVar('product_attachment', XOBJ_DTYPE_TXTBOX, null, false);
69
        $this->initVar('product_weight', XOBJ_DTYPE_TXTBOX, null, false);
70
        $this->initVar('product_unitmeasure2', XOBJ_DTYPE_TXTBOX, null, false);
71
        $this->initVar('product_vat_id', XOBJ_DTYPE_INT, null, false);
72
        $this->initVar('product_download_url', XOBJ_DTYPE_TXTBOX, null, false);
73
        $this->initVar('product_recommended', XOBJ_DTYPE_TXTBOX, null, false);
74
        $this->initVar('product_metakeywords', XOBJ_DTYPE_TXTBOX, null, false);
75
        $this->initVar('product_metadescription', XOBJ_DTYPE_TXTBOX, null, false);
76
        $this->initVar('product_metatitle', XOBJ_DTYPE_TXTBOX, null, false);
77
        $this->initVar('product_delivery_time', XOBJ_DTYPE_INT, null, false);
78
        $this->initVar('product_ecotaxe', XOBJ_DTYPE_TXTBOX, null, false);
79
        $this->initVar('product_property1', XOBJ_DTYPE_TXTBOX, null, false);
80
        $this->initVar('product_property2', XOBJ_DTYPE_TXTBOX, null, false);
81
        $this->initVar('product_property3', XOBJ_DTYPE_TXTBOX, null, false);
82
        $this->initVar('product_property4', XOBJ_DTYPE_TXTBOX, null, false);
83
        $this->initVar('product_property5', XOBJ_DTYPE_TXTBOX, null, false);
84
        $this->initVar('product_property6', XOBJ_DTYPE_TXTBOX, null, false);
85
        $this->initVar('product_property7', XOBJ_DTYPE_TXTBOX, null, false);
86
        $this->initVar('product_property8', XOBJ_DTYPE_TXTBOX, null, false);
87
        $this->initVar('product_property9', XOBJ_DTYPE_TXTBOX, null, false);
88
        $this->initVar('product_property10', XOBJ_DTYPE_TXTBOX, null, false);
89
90
        // Pour autoriser le html
91
        $this->initVar('dohtml', XOBJ_DTYPE_INT, 1, false);
92
    }
93
94
    /**
95
     * Indique si le produit courant est visible (périmé, encore en stock, en ligne etc)
96
     *
97
     * @return boolean
98
     * @since 2.3.2009.03.17
99
     */
100
    public function isProductVisible()
101
    {
102
        $isAdmin = Oledrion_utils::isAdmin();
103
        if ($this->getVar('product_online') == 0) {
104
            if (!$isAdmin) {
105
                return false;
106
            }
107
        }
108
        if (Oledrion_utils::getModuleOption('show_unpublished') == 0 && $this->getVar('product_submitted') > time()) {
109
            if (!$isAdmin) {
110
                return false;
111
            }
112
        }
113 View Code Duplication
        if (Oledrion_utils::getModuleOption('nostock_display') == 0 && $this->getVar('product_stock') == 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
114
            if (!$isAdmin) {
115
                return false;
116
            }
117
        }
118
119
        return true;
120
    }
121
122
    /**
123
     * Retourne l'URL de l'image du produit courant
124
     *
125
     * @return string L'URL
126
     */
127 View Code Duplication
    public function getPictureUrl()
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...
128
    {
129
        if (xoops_trim($this->getVar('product_image_url')) != '') {
130
            return OLEDRION_PICTURES_URL . '/' . $this->getVar('product_image_url');
131
        } else {
132
            return '';
133
        }
134
    }
135
136
    /**
137
     * Retourne le chemin de l'image du produit courant
138
     *
139
     * @return string Le chemin
140
     */
141
    public function getPicturePath()
142
    {
143
        if (xoops_trim($this->getVar('product_image_url')) != '') {
144
            return OLEDRION_PICTURES_PATH . '/' . $this->getVar('product_image_url');
145
        } else {
146
            return '';
147
        }
148
    }
149
150
    /**
151
     * Retourne l'URL de la vignette du produit courant
152
     *
153
     * @return string L'URL
154
     */
155
    public function getThumbUrl()
156
    {
157
        if (xoops_trim($this->getVar('product_thumb_url')) != '') {
158
            return OLEDRION_PICTURES_URL . '/' . $this->getVar('product_thumb_url');
159
        } else {
160
            return '';
161
        }
162
    }
163
164
    /**
165
     * Retourne l'URL de la vignette du produit courant
166
     *
167
     * @return string L'URL
168
     */
169
    public function getThumbPath()
170
    {
171
        if (xoops_trim($this->getVar('product_thumb_url')) != '') {
172
            return OLEDRION_PICTURES_PATH . '/' . $this->getVar('product_thumb_url');
173
        } else {
174
            return '';
175
        }
176
    }
177
178
    /**
179
     * Indique si l'image du produit existe
180
     *
181
     * @return boolean Vrai si l'image existe sinon faux
182
     */
183 View Code Duplication
    public function pictureExists()
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...
184
    {
185
        $return = false;
186
        if (xoops_trim($this->getVar('product_image_url')) != ''
187
            && file_exists(OLEDRION_PICTURES_PATH . '/' . $this->getVar('product_image_url'))
188
        ) {
189
            $return = true;
190
        }
191
192
        return $return;
193
    }
194
195
    /**
196
     * Indique si la vignette du produit existe
197
     *
198
     * @return boolean Vrai si l'image existe sinon faux
199
     */
200 View Code Duplication
    public function thumbExists()
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...
201
    {
202
        $return = false;
203
        if (xoops_trim($this->getVar('product_thumb_url')) != ''
204
            && file_exists(OLEDRION_PICTURES_PATH . '/' . $this->getVar('product_thumb_url'))
205
        ) {
206
            $return = true;
207
        }
208
209
        return $return;
210
    }
211
212
    /**
213
     * Supprime l'image associée à un produit
214
     *
215
     * @return void
216
     */
217 View Code Duplication
    public function deletePicture()
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...
218
    {
219
        if ($this->pictureExists()) {
220
            @unlink(OLEDRION_PICTURES_PATH . '/' . $this->getVar('product_image_url'));
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
221
        }
222
        $this->setVar('product_image_url', '');
223
    }
224
225
    /**
226
     * Indique si le fichier attaché à un produit existe
227
     *
228
     * @return boolean
229
     */
230 View Code Duplication
    public function attachmentExists()
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...
231
    {
232
        $return = false;
233
        if (xoops_trim($this->getVar('product_attachment')) != ''
234
            && file_exists(OLEDRION_ATTACHED_FILES_PATH . '/' . $this->getVar('product_attachment'))
235
        ) {
236
            $return = true;
237
        }
238
239
        return $return;
240
    }
241
242
    /**
243
     * Supprime le fichier attaché
244
     *
245
     * @return void
246
     */
247
    public function deleteAttachment()
248
    {
249
        if ($this->attachmentExists()) {
250
            @unlink(OLEDRION_ATTACHED_FILES_PATH . '/' . $this->getVar('product_attachment'));
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
251
        }
252
        $this->setVar('product_attachment', '');
253
    }
254
255
    /**
256
     * Supprime la miniature associée à un produit
257
     *
258
     * @return void
259
     */
260 View Code Duplication
    public function deleteThumb()
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...
261
    {
262
        if ($this->thumbExists()) {
263
            @unlink(OLEDRION_PICTURES_PATH . '/' . $this->getVar('product_thumb_url'));
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
264
        }
265
        $this->setVar('product_thumb_url', '');
266
    }
267
268
    /**
269
     * Supprime les 2 images (raccourcis)
270
     *
271
     * @return void
272
     */
273
    public function deletePictures()
274
    {
275
        $this->deletePicture();
276
        $this->deleteThumb();
277
    }
278
279
    /**
280
     * Retourne le prix TTC du prix réduit du produit courant
281
     *
282
     * @return floatval Le montant TTC du prix réduit
283
     */
284
    public function getDiscountTTC()
285
    {
286
        return Oledrion_utils::getAmountWithVat($this->getVar('product_discount_price', 'e'), $this->getVar('product_vat_id'));
287
    }
288
289
    /**
290
     * Retourne le montant TTC du prix normal du produit
291
     *
292
     * @return floatval
293
     */
294
    public function getTTC()
295
    {
296
        return Oledrion_utils::getAmountWithVat($this->getVar('product_price', 'e'), $this->getVar('product_vat_id'));
297
    }
298
299
    /**
300
     * Indique si le produit courant est recommandé.
301
     *
302
     * @param  bool $withDescription
303
     * @return bool Vrai si le produit est recommandé sinon faux
304
     */
305
    public function isRecommended($withDescription = false)
306
    {
307
        if ($this->getVar('product_recommended') != '0000-00-00') {
308
            return $withDescription ? _YES : true;
309
        } else {
310
            return $withDescription ? _NO : false;
311
        }
312
    }
313
314
    /**
315
     * Place le produit courant dans l'état "recommandé"
316
     *
317
     * @return void
318
     */
319
    public function setRecommended()
320
    {
321
        $this->setVar('product_recommended', date('Y-m-d'));
322
    }
323
324
    /**
325
     * Enlève "l'attribut" recommandé d'un produit
326
     *
327
     * @return void
328
     */
329
    public function unsetRecommended()
330
    {
331
        $this->setVar('product_recommended', '0000-00-00');
332
    }
333
334
    /**
335
     * Retourne l'image qui indique si le produit est recommandé ou pas
336
     *
337
     * @return string La chaine à utiliser pour voir l'image
338
     */
339
    public function recommendedPicture()
340
    {
341
        if ($this->isRecommended()) {
342
            return "<img src=\"" . OLEDRION_IMAGES_URL . "heart.png\" alt=\"" . _OLEDRION_IS_RECOMMENDED . "\" />&nbsp;";
343
        } else {
344
            return "<img src=\"" . OLEDRION_IMAGES_URL . "blank.gif\" alt=\"\" />";
345
        }
346
    }
347
348
    /**
349
     * Retourne le lien du produit courant en tenant compte de l'URL Rewriting
350
     *
351
     * @param  integer $product_id    L'identifiant du produit
352
     * @param  string  $product_title Le titre du produit
353
     * @param  boolean $shortVersion  Indique si on veut la version avec l'url complpète ou la version avec juste la page et le paramètre
354
     * @return string
355
     */
356
    public function getLink($product_id = 0, $product_title = '', $shortVersion = false)
357
    {
358
        $url = '';
0 ignored issues
show
Unused Code introduced by
$url 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...
359
        if ($product_id == 0 && $product_title == '') {
360
            $product_id    = $this->getVar('product_id');
361
            $product_title = $this->getVar('product_title', 'n');
362
        }
363
        if (Oledrion_utils::getModuleOption('urlrewriting') == 1) { // On utilise l'url rewriting
364
            if (!$shortVersion) {
365
                $url = OLEDRION_URL . 'product-' . $product_id . Oledrion_utils::makeSeoUrl($product_title) . '.html';
366
            } else {
367
                $url = 'product-' . $product_id . Oledrion_utils::makeSeoUrl($product_title) . '.html';
368
            }
369
        } else { // Pas d'utilisation de l'url rewriting
370
            if (!$shortVersion) {
371
                $url = OLEDRION_URL . 'product.php?product_id=' . $product_id;
372
            } else {
373
                $url = 'product.php?product_id=' . $product_id;
374
            }
375
        }
376
377
        return $url;
378
    }
379
380
    /**
381
     * Retourne le nombre d'attributs du produit courant
382
     *
383
     * @return integer
384
     * @since 2.3.2009.03.19
385
     */
386
    public function productAttributesCount()
387
    {
388
        return OledrionHandler::getInstance()->h_oledrion_attributes->getProductAttributesCount($this->getVar('product_id'));
389
    }
390
391
    /**
392
     * Retourne le nombre d'attributs obligatoires d'un produit
393
     *
394
     * @note  : La fonction est "doublée", elle se trouve içi et dans la classe des attributs pour des raisons de facilité (et de logique)
395
     *
396
     * @return integer
397
     * @since 2.3.2009.03.20
398
     */
399
    public function getProductMandatoryAttributesCount()
400
    {
401
        return OledrionHandler::getInstance()->h_oledrion_attributes->getProductMandatoryAttributesCount($this);
402
    }
403
404
    /**
405
     * Retourne la liste des attributs obligatoires du produit
406
     *
407
     * @return array
408
     * @since 2.3.2009.03.20
409
     */
410
    public function getProductMandatoryFieldsList()
411
    {
412
        return OledrionHandler::getInstance()->h_oledrion_attributes->getProductMandatoryFieldsList($this);
413
    }
414
415
    /**
416
     * Retourne la liste des attributs du produit courant
417
     *
418
     * @param  null $attributesIds
419
     * @return array Objets de type oledrion_attributes
420
     * @since 2.3.2009.03.20
421
     */
422
    public function getProductsAttributesList($attributesIds = null)
423
    {
424
        return OledrionHandler::getInstance()->h_oledrion_attributes->getProductsAttributesList($this->getVar('product_id'), $attributesIds);
425
    }
426
427
    /**
428
     * Retourne le montant HT initial des options
429
     *
430
     * @return float
431
     */
432
    public function getInitialOptionsPrice()
433
    {
434
        return OledrionHandler::getInstance()->h_oledrion_attributes->getInitialOptionsPrice($this);
435
    }
436
437
    /**
438
     *
439
     */
440
    public function isNewProduct()
441
    {
442
        $time = time() - (60 * 60 * 24 * 10);
443
        if ($this->getVar('product_submitted') > $time) {
444
            return 1;
445
        } else {
446
            return 0;
447
        }
448
    }
449
450
    /**
451
     * Retourne les éléments du produits formatés pour affichage
452
     *
453
     * @param  string $format Le format à utiliser
454
     * @return array  Les informations formatées
455
     */
456
    public function toArray($format = 's')
457
    {
458
        $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...
459
        $ret               = parent::toArray($format);
460
        $oledrion_Currency = Oledrion_Currency::getInstance();
461
        $ttc               = $finalPriceTTC = $this->getTTC();
462
        $finalPriceHT      = (float)$this->getVar('product_price');
463
464
        $ret['product_ecotaxe_formated'] = $oledrion_Currency->amountForDisplay($this->getVar('product_ecotaxe'));
465
466
        $ret['product_price_formated']          = $oledrion_Currency->amountForDisplay($this->getVar('product_price', 'e'));
467
        $ret['product_shipping_price_formated'] = $oledrion_Currency->amountForDisplay($this->getVar('product_shipping_price', 'e'));
468
        $ret['product_discount_price_formated'] = $oledrion_Currency->amountForDisplay($this->getVar('product_discount_price', 'e'));
469
        $ret['product_price_ttc']               = $oledrion_Currency->amountForDisplay($ttc);
470
        $ret['product_price_ttc_long']          = $oledrion_Currency->amountForDisplay($ttc, 'l');
471
472
        if ((int)$this->getVar('product_discount_price') > 0) { //geeker
473
            $finalPriceTTC                          = $this->getDiscountTTC();
474
            $finalPriceHT                           = (float)$this->getVar('product_discount_price', 'e');
475
            $ret['product_discount_price_ttc']      = $oledrion_Currency->amountForDisplay($this->getDiscountTTC());
476
            $ret['product_discount_price_ttc_long'] = $oledrion_Currency->amountForDisplay($this->getDiscountTTC(), 'l');
477
        } else {
478
            $ret['product_discount_price_ttc']      = '';
479
            $ret['product_discount_price_ttc_long'] = '';
480
        }
481
        // Les informations sur les attributs
482
        $attributesCount                 = $this->productAttributesCount();
483
        $ret['product_attributes_count'] = $attributesCount;
484
        if ($attributesCount > 0) {
485
            $optionsPrice                           = $this->getInitialOptionsPrice();
486
            $ret['product_price_formated']          = $oledrion_Currency->amountForDisplay((float)$this->getVar('product_price', 'e') + $optionsPrice);
487
            $ret['product_discount_price_formated'] = $oledrion_Currency->amountForDisplay((float)$this->getVar('product_discount_price', 'e') + $optionsPrice);
488
            $ret['product_price_ttc']               = $oledrion_Currency->amountForDisplay($ttc + $optionsPrice);
489
            $ret['product_price_ttc_long']          = $oledrion_Currency->amountForDisplay($ttc + $optionsPrice, 'l');
490
            if ((int)$this->getVar('product_discount_price') != 0) {
491
                $finalPriceTTC                          = $this->getDiscountTTC() + $optionsPrice;
492
                $finalPriceHT                           = (float)$this->getVar('product_discount_price', 'e') + $optionsPrice;
493
                $ret['product_discount_price_ttc']      = $oledrion_Currency->amountForDisplay((float)$this->getDiscountTTC() + $optionsPrice);
494
                $ret['product_discount_price_ttc_long'] = $oledrion_Currency->amountForDisplay((float)$this->getDiscountTTC() + $optionsPrice, 'l');
495
            }
496
        }
497
498
        $ret['product_final_price_ht_formated_long']  = $oledrion_Currency->amountForDisplay($finalPriceHT, 'l');
499
        $ret['product_final_price_ttc']               = $finalPriceTTC;
500
        $ret['product_final_price_ttc_javascript']    = Oledrion_utils::formatFloatForDB($finalPriceTTC);
501
        $ret['product_final_price_ttc_formated']      = $oledrion_Currency->amountForDisplay($finalPriceTTC);
502
        $ret['product_final_price_ttc_formated_long'] = $oledrion_Currency->amountForDisplay($finalPriceTTC, 'l');
503
        $ret['product_vat_amount_formated_long']      = $oledrion_Currency->amountForDisplay($finalPriceHT - $finalPriceTTC);
504
505
        $ret['product_tooltip']             = Oledrion_utils::makeInfotips($this->getVar('product_description'));
506
        $ret['product_url_rewrited']        = $this->getLink();
507
        $ret['product_href_title']          = Oledrion_utils::makeHrefTitle($this->getVar('product_title'));
508
        $ret['product_recommended']         = $this->isRecommended();
509
        $ret['product_recommended_picture'] = $this->recommendedPicture();
510
511
        $ret['product_image_full_url']  = $this->getPictureUrl();
512
        $ret['product_thumb_full_url']  = $this->getThumbUrl();
513
        $ret['product_image_full_path'] = $this->getPicturePath();
514
        $ret['product_thumb_full_path'] = $this->getThumbPath();
515
516
        $ret['product_shorten_summary']     = Oledrion_utils::truncate_tagsafe($this->getVar('product_summary'), OLEDRION_SUMMARY_MAXLENGTH);
517
        $ret['product_shorten_description'] = Oledrion_utils::truncate_tagsafe($this->getVar('product_description'), OLEDRION_SUMMARY_MAXLENGTH);
518
        $ret['product_new']                 = $this->isNewProduct();
519
520
        return $ret;
521
    }
522
}
523
524
/**
525
 * Class OledrionOledrion_productsHandler
526
 */
527
class OledrionOledrion_productsHandler 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...
528
{
529
    /**
530
     * OledrionOledrion_productsHandler constructor.
531
     * @param XoopsDatabase|null $db
532
     */
533
    public function __construct(XoopsDatabase $db)
534
    { //                            Table               Classe              Id          Libellé
535
        parent::__construct($db, 'oledrion_products', 'oledrion_products', 'product_id', 'product_title');
536
    }
537
538
    /**
539
     * Retourne la liste des x produits les plus vus par les visiteurs
540
     *
541
     * @param  Oledrion_parameters $parameters
542
     * @return array               Tableau de produits (sous la forme d'objets)
543
     * @internal param int $start Début des données
544
     * @internal param int $limit Nombre maximum d'enregistrements à renvoyer
545
     * @internal param int $category Identifiant de la catégorie (évenutellement)
546
     * @internal param string $sort Champ sur lequel trier
547
     * @internal param string $order Sens du tri
548
     */
549 View Code Duplication
    public function getMostViewedProducts(Oledrion_parameters $parameters)
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...
550
    {
551
        $parameters = $parameters->extend(new Oledrion_parameters(array(
0 ignored issues
show
Documentation introduced by
new \Oledrion_parameters...s', 'order' => 'DESC')) is of type object<Oledrion_parameters>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
552
                                                                      'start'    => 0,
553
                                                                      'limit'    => 0,
554
                                                                      'category' => 0,
555
                                                                      'sort'     => 'product_hits',
556
                                                                      'order'    => 'DESC'
557
                                                                  )));
558
        $data       = array();
0 ignored issues
show
Unused Code introduced by
$data 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...
559
        $criteria   = new CriteriaCompo();
560
        $criteria->add(new Criteria('product_online', 1, '='));
561
        if (Oledrion_utils::getModuleOption('show_unpublished') == 0) { // Ne pas afficher les produits qui ne sont pas publiés
562
            $criteria->add(new Criteria('product_submitted', time(), '<='));
563
        }
564
        if (Oledrion_utils::getModuleOption('nostock_display') == 0) { // Se limiter aux seuls produits encore en stock
565
            $criteria->add(new Criteria('product_stock', 0, '>'));
566
        }
567
        if (is_array($parameters['category']) && count($parameters['category']) > 0) {
568
            $criteria->add(new Criteria('product_cid', '(' . implode(',', $parameters['category']) . ')', 'IN'));
569
        } elseif ($parameters['category'] != 0) {
570
            $criteria->add(new Criteria('product_cid', (int)$parameters['category'], '='));
571
        }
572
        $criteria->add(new Criteria('product_hits', 0, '>'));
573
574
        $criteria->setLimit($parameters['limit']);
575
        $criteria->setStart($parameters['start']);
576
        $criteria->setSort($parameters['sort']);
577
        $criteria->setOrder($parameters['order']);
578
        $data = $this->getObjects($criteria, true);
579
580
        return $data;
581
    }
582
583
    /**
584
     * Retourne la liste des x produits les mieux notés par les visiteurs
585
     *
586
     * @param  Oledrion_parameters $parameters
587
     * @return array               Tableau de produits (sous la forme d'objets)
588
     * @internal param int $start Début des données
589
     * @internal param int $limit Nombre maximum d'enregistrements à renvoyer
590
     * @internal param int $category Identifiant de la catégorie (évenutellement)
591
     */
592 View Code Duplication
    public function getBestRatedProducts(Oledrion_parameters $parameters)
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...
593
    {
594
        $parameters = $parameters->extend(new Oledrion_parameters(array(
0 ignored issues
show
Documentation introduced by
new \Oledrion_parameters...g', 'order' => 'DESC')) is of type object<Oledrion_parameters>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
595
                                                                      'start'    => 0,
596
                                                                      'limit'    => 0,
597
                                                                      'category' => 0,
598
                                                                      'sort'     => 'product_rating',
599
                                                                      'order'    => 'DESC'
600
                                                                  )));
601
        $data       = array();
0 ignored issues
show
Unused Code introduced by
$data 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...
602
        $criteria   = new CriteriaCompo();
603
        $criteria->add(new Criteria('product_online', 1, '='));
604
        $criteria->add(new Criteria('product_rating', 0, '>')); // Se limiter aux seuls produits qui ont été vraiment notés
605
        if (Oledrion_utils::getModuleOption('show_unpublished') == 0) { // Ne pas afficher les produits qui ne sont pas publiés
606
            $criteria->add(new Criteria('product_submitted', time(), '<='));
607
        }
608
        if (Oledrion_utils::getModuleOption('nostock_display') == 0) { // Se limiter aux seuls produits encore en stock
609
            $criteria->add(new Criteria('product_stock', 0, '>'));
610
        }
611
        if (is_array($parameters['category']) && count($parameters['category']) > 0) {
612
            $criteria->add(new Criteria('product_cid', '(' . implode(',', $parameters['category']) . ')', 'IN'));
613
        } elseif ($parameters['category'] != 0) {
614
            $criteria->add(new Criteria('product_cid', (int)$parameters['category'], '='));
615
        }
616
        $criteria->setLimit($parameters['limit']);
617
        $criteria->setStart($parameters['start']);
618
        $criteria->setSort($parameters['sort']);
619
        $criteria->setOrder($parameters['order']);
620
        $data = $this->getObjects($criteria, true);
621
622
        return $data;
623
    }
624
625
    /**
626
     * Retourne la liste des x derniers produits recommandés
627
     *
628
     * @param  Oledrion_parameters $parameters
629
     * @return array               Tableau de produits (sous la forme d'objets)
630
     * @internal param int $start Indice de départ
631
     * @internal param int $limit Nombre maximum d'enregistrements à renvoyer
632
     * @internal param int $category Identifiant de la catégorie (évenutellement)
633
     */
634 View Code Duplication
    public function getRecentRecommended(Oledrion_parameters $parameters)
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...
635
    {
636
        $parameters = $parameters->extend(new Oledrion_parameters(array(
0 ignored issues
show
Documentation introduced by
new \Oledrion_parameters...d', 'order' => 'DESC')) is of type object<Oledrion_parameters>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
637
                                                                      'start'    => 0,
638
                                                                      'limit'    => 0,
639
                                                                      'category' => 0,
640
                                                                      'sort'     => 'product_recommended',
641
                                                                      'order'    => 'DESC'
642
                                                                  )));
643
        $data       = array();
0 ignored issues
show
Unused Code introduced by
$data 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...
644
        $criteria   = new CriteriaCompo();
645
        $criteria->add(new Criteria('product_online', 1, '='));
646
        $criteria->add(new Criteria('product_recommended', '0000-00-00', '<>'));
647
        if (Oledrion_utils::getModuleOption('show_unpublished') == 0) { // Ne pas afficher les produits qui ne sont pas publiés
648
            $criteria->add(new Criteria('product_submitted', time(), '<='));
649
        }
650
        if (Oledrion_utils::getModuleOption('nostock_display') == 0) { // Se limiter aux seuls produits encore en stock
651
            $criteria->add(new Criteria('product_stock', 0, '>'));
652
        }
653
        if (is_array($parameters['category'])) {
654
            $criteria->add(new Criteria('product_cid', '(' . implode(',', $parameters['category']) . ')', 'IN'));
655
        } elseif ($parameters['category'] != 0) {
656
            $criteria->add(new Criteria('product_cid', (int)$parameters['category'], '='));
657
        }
658
        $criteria->setLimit($parameters['limit']);
659
        $criteria->setStart($parameters['start']);
660
        $criteria->setSort($parameters['sort']);
661
        $criteria->setOrder($parameters['order']);
662
        $data = $this->getObjects($criteria, true);
663
664
        return $data;
665
    }
666
667
    /**
668
     * Retourne le nombre total de produits recommandés
669
     *
670
     * @return integer Le nombre total de produits recommandés
671
     */
672 View Code Duplication
    public function getRecommendedCount()
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...
673
    {
674
        $criteria = new CriteriaCompo();
675
        $criteria->add(new Criteria('product_online', 1, '='));
676
        $criteria->add(new Criteria('product_recommended', '0000-00-00', '<>'));
677
        if (Oledrion_utils::getModuleOption('show_unpublished') == 0) { // Ne pas afficher les produits qui ne sont pas publiés
678
            $criteria->add(new Criteria('product_submitted', time(), '<='));
679
        }
680
        if (Oledrion_utils::getModuleOption('nostock_display') == 0) { // Se limiter aux seuls produits encore en stock
681
            $criteria->add(new Criteria('product_stock', 0, '>'));
682
        }
683
684
        return $this->getCount($criteria);
685
    }
686
687
    /**
688
     * Retourne la liste des x derniers produits parus toutes catégories confondues ou dans une catégorie spécifique
689
     *
690
     * @param  Oledrion_parameters $parameters
691
     * @return array               Tableau de produits (sous la forme d'objets)
692
     * @internal param int $start Début des données
693
     * @internal param int $limit Nombre maximum d'enregistrements à renvoyer
694
     * @internal param mixed $category Identifiant de la catégorie (évenutellement) ou tableau d'ID ou rien du tout
695
     * @internal param string $sort Champ(s) à utiliser pour le tri
696
     * @internal param string $order Ordre de tri
697
     * @internal param int $excluded Produit à exclure de la liste (éventuellement)
698
     * @internal param bool $thisMonthOnly Indique s'il ne faut prendre que les produits du mois
699
     */
700
    public function getRecentProducts(Oledrion_parameters $parameters)
701
    {
702
        $parameters = $parameters->extend(new Oledrion_parameters(array(
0 ignored issues
show
Documentation introduced by
new \Oledrion_parameters...isMonthOnly' => false)) is of type object<Oledrion_parameters>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
703
                                                                      'start'         => 0,
704
                                                                      'limit'         => 0,
705
                                                                      'category'      => 0,
706
                                                                      'sort'          => 'product_submitted DESC, product_title',
707
                                                                      'order'         => '',
708
                                                                      'excluded'      => 0,
709
                                                                      'thisMonthOnly' => false
710
                                                                  )));
711
        $data       = array();
0 ignored issues
show
Unused Code introduced by
$data 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...
712
        $criteria   = new CriteriaCompo();
713
        $criteria->add(new Criteria('product_online', 1, '='));
714
        if (Oledrion_utils::getModuleOption('show_unpublished') == 0) { // Ne pas afficher les produits qui ne sont pas publiés
715
            $criteria->add(new Criteria('product_submitted', time(), '<='));
716
        }
717
        if (Oledrion_utils::getModuleOption('nostock_display') == 0) { // Se limiter aux seuls produits encore en stock
718
            $criteria->add(new Criteria('product_stock', 0, '>'));
719
        }
720
        if (is_array($parameters['category']) && count($parameters['category']) > 0) {
721
            $criteria->add(new Criteria('product_cid', '(' . implode(',', $parameters['category']) . ')', 'IN'));
722
        } elseif ($parameters['category'] > 0) {
723
            $criteria->add(new Criteria('product_cid', (int)$parameters['category'], '='));
724
        }
725
        if ($parameters['excluded'] > 0) {
726
            $criteria->add(new Criteria('product_id', $parameters['excluded'], '<>'));
727
        }
728
729
        if ($parameters['thisMonthOnly']) {
730
            $criteria->add(Oledrion_utils::getThisMonthCriteria());
731
        }
732
733
        $criteria->setLimit($parameters['limit']);
734
        $criteria->setStart($parameters['start']);
735
        $criteria->setSort($parameters['sort']);
736
        if (xoops_trim($parameters['order']) != '') {
737
            $criteria->setOrder($parameters['order']);
738
        }
739
        $data = $this->getObjects($criteria, true);
740
741
        return $data;
742
    }
743
744
    /**
745
     * Retourne le nombre total de produits récents (éventuellement dans une catégorie)
746
     *
747
     * @param  mixed   $category        Array ou Integer
748
     * @param  integer $excludedProduct ID d'un produit à exclure
749
     * @return integer
750
     */
751
    public function getRecentProductsCount($category = 0, $excludedProduct = 0)
752
    {
753
        $criteria = new CriteriaCompo();
754
        $criteria->add(new Criteria('product_online', 1, '='));
755
        if (Oledrion_utils::getModuleOption('show_unpublished') == 0) { // Ne pas afficher les produits qui ne sont pas publiés
756
            $criteria->add(new Criteria('product_submitted', time(), '<='));
757
        }
758
        if (Oledrion_utils::getModuleOption('nostock_display') == 0) { // Se limiter aux seuls produits encore en stock
759
            $criteria->add(new Criteria('product_stock', 0, '>'));
760
        }
761 View Code Duplication
        if (is_array($category)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
762
            $criteria->add(new Criteria('product_cid', '(' . implode(',', $category) . ')', 'IN'));
763
        } elseif ($category > 0) {
764
            $criteria->add(new Criteria('product_cid', (int)$category, '='));
765
        }
766
        if ($excludedProduct > 0) {
767
            $criteria->add(new Criteria('product_id', $excludedProduct, '<>'));
768
        }
769
770
        return $this->getCount($criteria);
771
    }
772
773
    /**
774
     * Retourne la liste des produits qui correspondent à des "critères" de manière à les utiliser pour la newsletter
775
     *
776
     * @param  Oledrion_parameters $parameters
777
     * @return array               Des objects de type produits
778
     * @internal param int $startingDate Date de soumission du produit à prendre comme borne inférieure
779
     * @internal param int $endingDate Date de soumission du produit à prendre comme borne supérieure
780
     * @internal param mixed $category Soit un tableau d'ID de catégories soit un ID unique de catégorie
781
     * @internal param int $start Position de départ
782
     * @internal param int $limit Nombre d'enregistrements à retourner
783
     */
784 View Code Duplication
    public function getProductsForNewsletter(Oledrion_parameters $parameters)
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...
785
    {
786
        $parameters = $parameters->extend(new Oledrion_parameters(array(
0 ignored issues
show
Documentation introduced by
new \Oledrion_parameters...t' => 0, 'limit' => 0)) is of type object<Oledrion_parameters>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
787
                                                                      'startingDate' => 0,
788
                                                                      'endingDate'   => 0,
789
                                                                      'category'     => 0,
790
                                                                      'start'        => 0,
791
                                                                      'limit'        => 0
792
                                                                  )));
793
        $data       = array();
0 ignored issues
show
Unused Code introduced by
$data 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...
794
        $criteria   = new CriteriaCompo();
795
        $criteria->add(new Criteria('product_online', 1, '='));
796
        $criteria->add(new Criteria('product_submitted', $parameters['startingDate'], '>='));
797
        $criteria->add(new Criteria('product_submitted', $parameters['endingDate'], '<='));
798
        if (Oledrion_utils::getModuleOption('show_unpublished') == 0) { // Ne pas afficher les produits qui ne sont pas publiés
799
            $criteria->add(new Criteria('product_submitted', time(), '<='));
800
        }
801
        if (Oledrion_utils::getModuleOption('nostock_display') == 0) { // Se limiter aux seuls produits encore en stock
802
            $criteria->add(new Criteria('product_stock', 0, '>'));
803
        }
804
        if (is_array($parameters['category'])) {
805
            $criteria->add(new Criteria('product_cid', '(' . implode(',', $parameters['category']) . ')', 'IN'));
806
        } elseif ($parameters['category'] > 0) {
807
            $criteria->add(new Criteria('product_cid', (int)$parameters['category'], '='));
808
        }
809
        $criteria->setLimit($parameters['limit']);
810
        $criteria->setStart($parameters['start']);
811
        $criteria->setSort('product_title');
812
        $data = $this->getObjects($criteria, true);
813
814
        return $data;
815
    }
816
817
    /**
818
     * Retourne le nombre total de produits publiés dans la base en tenant compte des préférences du module
819
     *
820
     * @param  int|intefer $product_cid Catégorie du produit
821
     * @return int         Le nombre de produits publiés
822
     */
823 View Code Duplication
    public function getTotalPublishedProductsCount($product_cid = 0)
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...
824
    {
825
        $criteria = new CriteriaCompo();
826
        $criteria->add(new Criteria('product_online', 1, '='));
827
        if (Oledrion_utils::getModuleOption('show_unpublished') == 0) { // Ne pas afficher les produits qui ne sont pas publiés
828
            $criteria->add(new Criteria('product_submitted', time(), '<='));
829
        }
830
        if (Oledrion_utils::getModuleOption('nostock_display') == 0) { // Se limiter aux seuls produits encore en stock
831
            $criteria->add(new Criteria('product_stock', 0, '>'));
832
        }
833
        if ($product_cid > 0) {
834
            $criteria->add(new Criteria('product_cid', (int)$product_cid, '='));
835
        }
836
837
        return $this->getCount($criteria);
838
    }
839
840
    /**
841
     * Récupération de l'ID et du titre d'une série de produits répondants à un critère
842
     *
843
     * @param  object $criteria critère de sélection
844
     * @return array  Tableau dont la clé = ID produit et la valeur le titre du produit
845
     */
846
    public function getIdTitle($criteria)
847
    {
848
        global $myts;
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...
849
        $ret = array();
850
        $sql = 'SELECT product_id, product_title FROM ' . $this->table;
851
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of returns inconsistent results on some PHP versions for interfaces; you could instead use ReflectionClass::implementsInterface.
Loading history...
852
            $sql .= ' ' . $criteria->renderWhere();
853
            if ($criteria->getSort() != '') {
854
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
855
            }
856
            $limit = $criteria->getLimit();
857
            $start = $criteria->getStart();
858
        }
859
        $result = $this->db->query($sql, $limit, $start);
0 ignored issues
show
Bug introduced by
The variable $limit 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...
Bug introduced by
The variable $start 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...
860
        if (!$result) {
861
            return $ret;
862
        }
863
        while ($myrow = $this->db->fetchArray($result)) {
864
            $ret[$myrow['product_id']] = $myts->htmlSpecialChars($myrow['product_title']);
865
        }
866
867
        return $ret;
868
    }
869
870
    /**
871
     * Mise à jour du compteur de lectures du produit
872
     *
873
     * @param  integer $product_id L'identifiant du produit dont il faut mettre à jour le compteur de lectures
874
     * @return boolean Le résultat de la mise à jour
875
     */
876
    public function addCounter($product_id)
877
    {
878
        $sql = 'UPDATE ' . $this->table . ' SET product_hits = product_hits + 1 WHERE product_id= ' . (int)$product_id;
879
880
        // Note, pas de mise à jour du cache !
881
        return $this->db->queryF($sql);
882
    }
883
884
    /**
885
     * Mise à jour de la notation d'un produit
886
     *
887
     * @param  integer $product_id Identifiant du produit
888
     * @param  float   $rating     la notation
889
     * @param  integer $votes      Le nombre de votes du produit
890
     * @return boolean Le résultat de la mise à jour
891
     */
892
    public function updateRating($product_id, $rating, $votes)
893
    {
894
        $sql = 'UPDATE ' . $this->table . ' SET product_rating = ' . (int)$rating . ', product_votes = ' . (int)$votes . ' WHERE product_id = ' . (int)$product_id;
895
896
        return $this->db->queryF($sql);
897
    }
898
899
    /**
900
     * Mise à jour du nombre de commentaires d'un produit
901
     *
902
     * @param integer $product_id    Identifiant du produit
903
     * @param integer $commentsCount Nombre total de commentaires
904
     */
905
    public function updateCommentsCount($product_id, $commentsCount)
906
    {
907
        $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...
908
        $product = $this->get($product_id);
909
        if (is_object($product)) {
910
            $criteria = new Criteria('product_id', $product_id, '=');
911
            $this->updateAll('product_comments', $commentsCount, $criteria, true);
912
        }
913
    }
914
915
    /**
916
     * Retourne x produits au hasard
917
     *
918
     * @param  Oledrion_parameters $parameters
919
     * @return array               Tableau de produits (sous la forme d'objets)
920
     * @internal param int $start Début des données
921
     * @internal param int $limit Nombre maximum d'enregistrements à renvoyer
922
     * @internal param int $category Identifiant de la catégorie (évenutellement)
923
     * @internal param string $sort Zone sur laquelle faire le tri
924
     * @internal param string $order Ordre de tri
925
     * @internal param bool $thisMonthOnly Uniquement les produits du mois en cours ?
926
     */
927 View Code Duplication
    public function getRandomProducts(Oledrion_parameters $parameters)
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...
928
    {
929
        $parameters = $parameters->extend(new Oledrion_parameters(array(
0 ignored issues
show
Documentation introduced by
new \Oledrion_parameters...isMonthOnly' => false)) is of type object<Oledrion_parameters>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
930
                                                                      'start'         => 0,
931
                                                                      'limit'         => 0,
932
                                                                      'category'      => 0,
933
                                                                      'sort'          => 'RAND()',
934
                                                                      'order'         => 'ASC',
935
                                                                      'thisMonthOnly' => false
936
                                                                  )));
937
        $data       = array();
0 ignored issues
show
Unused Code introduced by
$data 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...
938
        $criteria   = new CriteriaCompo();
939
        $criteria->add(new Criteria('product_online', 1, '='));
940
        if (Oledrion_utils::getModuleOption('show_unpublished') == 0) { // Ne pas afficher les produits qui ne sont pas publiés
941
            $criteria->add(new Criteria('product_submitted', time(), '<='));
942
        }
943
        if (Oledrion_utils::getModuleOption('nostock_display') == 0) { // Se limiter aux seuls produits encore en stock
944
            $criteria->add(new Criteria('product_stock', 0, '>'));
945
        }
946
        if (is_array($parameters['category'])) {
947
            $criteria->add(new Criteria('product_cid', '(' . implode(',', $parameters['category']) . ')', 'IN'));
948
        } elseif ($parameters['category'] != 0) {
949
            $criteria->add(new Criteria('product_cid', (int)$parameters['category'], '='));
950
        }
951
952
        if ($parameters['thisMonthOnly']) {
953
            $criteria->add(Oledrion_utils::getThisMonthCriteria());
954
        }
955
956
        $criteria->setLimit($parameters['limit']);
957
        $criteria->setStart($parameters['start']);
958
        $criteria->setSort($parameters['sort']);
959
        $criteria->setOrder($parameters['order']);
960
        $data = $this->getObjects($criteria, true);
961
962
        return $data;
963
    }
964
965
    /**
966
     * Retourne x produits en promo
967
     *
968
     * @param  Oledrion_parameters $parameters
969
     * @return array               Tableau de produits (sous la forme d'objets)
970
     * @internal param int $start Début des données
971
     * @internal param int $limit Nombre maximum d'enregistrements à renvoyer
972
     * @internal param int $category Identifiant de la catégorie (évenutellement)
973
     */
974 View Code Duplication
    public function getPromotionalProducts(Oledrion_parameters $parameters)
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...
975
    {
976
        $parameters = $parameters->extend(new Oledrion_parameters(array(
0 ignored issues
show
Documentation introduced by
new \Oledrion_parameters...e', 'order' => 'DESC')) is of type object<Oledrion_parameters>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
977
                                                                      'start'    => 0,
978
                                                                      'limit'    => 0,
979
                                                                      'category' => 0,
980
                                                                      'sort'     => 'product_title',
981
                                                                      'order'    => 'DESC'
982
                                                                  )));
983
        $data       = array();
0 ignored issues
show
Unused Code introduced by
$data 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...
984
        $criteria   = new CriteriaCompo();
985
        $criteria->add(new Criteria('product_online', 1, '='));
986
        if (Oledrion_utils::getModuleOption('show_unpublished') == 0) { // Ne pas afficher les produits qui ne sont pas publiés
987
            $criteria->add(new Criteria('product_submitted', time(), '<='));
988
        }
989
        if (Oledrion_utils::getModuleOption('nostock_display') == 0) { // Se limiter aux seuls produits encore en stock
990
            $criteria->add(new Criteria('product_stock', 0, '>'));
991
        }
992
        if (is_array($parameters['category'])) {
993
            $criteria->add(new Criteria('product_cid', '(' . implode(',', $parameters['category']) . ')', 'IN'));
994
        } elseif ($parameters['category'] != 0) {
995
            $criteria->add(new Criteria('product_cid', (int)$parameters['category'], '='));
996
        }
997
        $criteria->add(new Criteria('product_discount_price', 0, '>'));
998
        $criteria->setLimit($parameters['limit']);
999
        $criteria->setStart($parameters['start']);
1000
        $criteria->setSort($parameters['sort']);
1001
        $criteria->setOrder($parameters['order']);
1002
        $data = $this->getObjects($criteria, true);
1003
1004
        return $data;
1005
    }
1006
1007
    /**
1008
     * Retourne les produits dont les stocks sont bas
1009
     *
1010
     * @param  integer $start Début des données
1011
     * @param  integer $limit Nombre maximum d'enregistrements à renvoyer
1012
     * @return array   Tableau de produits (sous la forme d'objets)
1013
     */
1014
    public function getLowStocks($start = 0, $limit = 0)
1015
    {
1016
        $ret = array();
1017
        $sql = 'SELECT * FROM ' . $this->table . ' WHERE product_online = 1';
1018
        if (Oledrion_utils::getModuleOption('show_unpublished') == 0) { // Ne pas afficher les produits qui ne sont pas publiés
1019
            $sql .= ' AND product_submitted <= ' . time();
1020
        }
1021
        $sql .= ' AND product_stock <= product_alert_stock ';
1022
        $sql .= ' AND product_alert_stock > 0';
1023
        $sql .= ' ORDER BY product_stock';
1024
        $result = $this->db->query($sql, $limit, $start);
1025
        if (!$result) {
1026
            return $ret;
1027
        }
1028
1029
        $ret = $this->convertResultSet($result, true, true);
1030
1031
        return $ret;
1032
    }
1033
1034
    /**
1035
     * Retourne le nombre de produits dont la quantité en stock est inférieure ou égale à la quantité d'alerte
1036
     *
1037
     * @return integer Le nombre de produits concernés
1038
     */
1039
    public function getLowStocksCount()
1040
    {
1041
        $ret = array();
1042
        $sql = 'SELECT Count(*) as cpt FROM ' . $this->table . ' WHERE product_online = 1';
1043
        if (Oledrion_utils::getModuleOption('show_unpublished') == 0) { // Ne pas afficher les produits qui ne sont pas publiés
1044
            $sql .= ' AND product_submitted <= ' . time();
1045
        }
1046
        $sql .= ' AND product_stock <= product_alert_stock ';
1047
        $sql .= ' AND product_alert_stock > 0';
1048
        $result = $this->db->query($sql);
1049
        if (!$result) {
1050
            return $ret;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $ret; (array) is incompatible with the return type documented by OledrionOledrion_product...dler::getLowStocksCount of type integer.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
1051
        }
1052
        $count = 0;
1053
        list($count) = $this->db->fetchRow($result);
1054
1055
        return $count;
1056
    }
1057
1058
    /**
1059
     * Augmente les quantités en stock d'un produit
1060
     *
1061
     * @param  object $product  Objet produit
1062
     * @param         $quantity $quantity Quantité à rajouter
0 ignored issues
show
Documentation introduced by
The doc-type $quantity could not be parsed: Unknown type name "$quantity" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
1063
     * @return bool
1064
     */
1065
    public function increaseStock($product, $quantity = 1)
1066
    {
1067
        $product->setVar('product_stock', $product->getVar('product_stock') + $quantity);
1068
        $this->insert($product, true);
1069
1070
        return true;
1071
    }
1072
1073
    /**
1074
     * Diminue les quantités en stock d'un produit
1075
     *
1076
     * @param  object $product  Objet produit
1077
     * @param         $quantity $quantity Quantité à soustraire
0 ignored issues
show
Documentation introduced by
The doc-type $quantity could not be parsed: Unknown type name "$quantity" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
1078
     * @return bool
1079
     */
1080
    public function decreaseStock(&$product, $quantity = 1)
1081
    {
1082
        if ($product->getVar('product_stock') - $quantity > 0) {
1083
            $product->setVar('product_stock', $product->getVar('product_stock') - $quantity);
1084
            $this->insert($product, true);
1085
        } else {
1086
            $product->setVar('product_stock', 0);
1087
        }
1088
1089
        return true;
1090
    }
1091
1092
    /**
1093
     * Indique si la quantité d'alerte d'un produit est atteinte
1094
     *
1095
     * @param $product
1096
     * @return bool Vrai si la quantité d'alerte est atteinte, sinon faux
1097
     * @internal param object $products L'objet produit concerné
1098
     */
1099
    public function isAlertStockReached(&$product)
1100
    {
1101
        if ($product->getVar('product_stock') < $product->getVar('product_alert_stock')) {
1102
            return true;
1103
        } else {
1104
            return false;
1105
        }
1106
    }
1107
1108
    /**
1109
     * Méthode chargée de vérifier si le stock d'alerte est atteint et si c'est le cas, d'envoyer une alerte
1110
     *
1111
     * @param  object $product Produit dont il faut faire la vérification
1112
     * @return boolean vrai si l'alerte à du être générée sinon faux
1113
     */
1114
    public function verifyLowStock(&$product)
1115
    {
1116
        if ($this->isAlertStockReached($product)) {
1117
            $msg                    = array();
1118
            $msg['PRODUCT_NAME']    = $product->getVar('product_title');
1119
            $msg['ACTUAL_QUANTITY'] = $product->getVar('product_stock');
1120
            $msg['ALERT_QUANTITY']  = $product->getVar('product_alert_stock');
1121
            $msg['PUBLIC_URL']      = $product->getLink();
1122
            $msg['ADMIN_URL']       = OLEDRION_URL . 'admin/index.php?op=editproduct&id=' . $product->getVar('product_id');
1123
            Oledrion_utils::sendEmailFromTpl('shop_lowstock.tpl', Oledrion_utils::getEmailsFromGroup(Oledrion_utils::getModuleOption('stock_alert_email')), _OLEDRION_STOCK_ALERT, $msg);
1124
1125
            return true;
1126
        } else {
1127
            return false;
1128
        }
1129
    }
1130
1131
    /**
1132
     * Retourne la plus petite date de création d'un produit ainsi que la "plus grande" date de création d'un produit
1133
     *
1134
     * @param  integer $minDate Date mini (parmètre de sortie)
1135
     * @param  integer $maxDate Date maxi (paramètre de sortie)
1136
     * @return boolean Vrai si on a pu récupérer ces valeurs, faux sinon
1137
     */
1138
    public function getMinMaxPublishedDate(&$minDate, &$maxDate)
1139
    {
1140
        $sql    = 'SELECT Min(product_submitted) AS minDate, Max(product_submitted) as maxDate FROM ' . $this->table . ' WHERE product_online = 1 ';
1141
        $result = $this->db->query($sql);
1142
        if (!$result) {
1143
            return false;
1144
        }
1145
        $myrow   = $this->db->fetchArray($result);
1146
        $minDate = $myrow['minDate'];
1147
        $maxDate = $myrow['maxDate'];
1148
1149
        return true;
1150
    }
1151
1152
    /**
1153
     * Retourne des produits en fonction de leur IDs tout en tenant compte du fait qu'ils sont en ligne et payés !
1154
     *
1155
     * @param  array   $ids     Les identifiants des produits
1156
     * @param  boolean $showAll Afficher les produits même s'ils ne sont plus en stock ?
1157
     * @return array   Tableau d'objets de type oledrion_products, Clé = Id Produit
1158
     */
1159
    public function getProductsFromIDs($ids, $showAll = false)
1160
    {
1161
        $ret = array();
1162
        if (is_array($ids)) {
1163
            $criteria = new CriteriaCompo();
1164
            if (Oledrion_utils::getModuleOption('show_unpublished') == 0) { // Ne pas afficher les produits qui ne sont pas publiés
1165
                $criteria->add(new Criteria('product_submitted', time(), '<='));
1166
            }
1167 View Code Duplication
            if (Oledrion_utils::getModuleOption('nostock_display') == 0
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1168
                && !$showAll
1169
            ) { // Se limiter aux seuls produits encore en stock
1170
                $criteria->add(new Criteria('product_stock', 0, '>'));
1171
            }
1172
            $criteria->add(new Criteria('product_id', '(' . implode(',', $ids) . ')', 'IN'));
1173
            $ret = $this->getObjects($criteria, true, true, '*', false);
1174
        }
1175
1176
        return $ret;
1177
    }
1178
1179
    /**
1180
     * Retourne le nombre de produits d'une ou de plusieurs catégories
1181
     *
1182
     * @param  mixed $cat_cid Soit un ID de catégorie unique soit un tableau d'ID de catégories
1183
     * @return integer Le nombre de produits associés à cette catégorie
1184
     */
1185
    public function getCategoryProductsCount($cat_cid)
1186
    {
1187 View Code Duplication
        if (is_array($cat_cid)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1188
            $lst_ids  = implode(',', $cat_cid);
1189
            $criteria = new Criteria('product_cid', '(' . $lst_ids . ')', 'IN');
1190
        } else {
1191
            $criteria = new Criteria('product_cid', $cat_cid, '=');
1192
        }
1193
1194
        return $this->getCount($criteria);
1195
    }
1196
1197
    /**
1198
     * Retourne le nombre de produits associés à un vendeur
1199
     *
1200
     * @param  integer $product_vendor_id L'ID du vendeur
1201
     * @return integer Le nombre de produits
1202
     */
1203
    public function getVendorProductsCount($product_vendor_id)
1204
    {
1205
        $criteria = new Criteria('product_vendor_id', $product_vendor_id, '=');
1206
1207
        return $this->getCount($criteria);
1208
    }
1209
1210
    /**
1211
     * Retourne le nombre de produits associés à une TVA
1212
     *
1213
     * @param  integer $product_vat_id L'identifiant de la TVA
1214
     * @return integer Le nombre de produits
1215
     */
1216
    public function getVatProductsCount($product_vat_id)
1217
    {
1218
        $criteria = new Criteria('product_vat_id', $product_vat_id, '=');
1219
1220
        return $this->getCount($criteria);
1221
    }
1222
1223
    /**
1224
     * Clone d'un produit
1225
     *
1226
     * @param  object|Oledrion_products $originalProduct Le produit à cloner
1227
     * @return mixed                    Soit l'objet représentant le nouveau produit soit false
1228
     */
1229
    public function cloneProduct(Oledrion_products $originalProduct)
1230
    {
1231
        global $h_oledrion_productsmanu, $h_oledrion_files, $h_oledrion_productsmanu, $h_oledrion_related, $oledrionHandlers;
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...
1232
        $newProduct =& $originalProduct->xoopsClone();
1233 View Code Duplication
        if (OLEDRION_DUPLICATED_PLACE === 'right') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1234
            $newProduct->setVar('product_title', $originalProduct->getVar('product_title') . ' ' . _AM_OLEDRION_DUPLICATED);
1235
        } else {
1236
            $newProduct->setVar('product_title', _AM_OLEDRION_DUPLICATED . ' ' . $originalProduct->getVar('product_title'));
1237
        }
1238
        $newProduct->setVar('product_id', 0);
1239
        $newProduct->setNew();
1240
1241
        // Copie des 2 images
1242 View Code Duplication
        if (xoops_trim($originalProduct->getVar('product_image_url')) != '') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1243
            $resCopy = Oledrion_utils::duplicateFile(OLEDRION_PICTURES_PATH, $originalProduct->getVar('product_image_url'));
1244
            if ($resCopy !== false) {
1245
                $newProduct->setVar('product_image_url', $resCopy);
1246
            }
1247
        }
1248 View Code Duplication
        if (xoops_trim($originalProduct->getVar('product_thumb_url')) != '') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1249
            $resCopy = Oledrion_utils::duplicateFile(OLEDRION_PICTURES_PATH, $originalProduct->getVar('product_thumb_url'));
1250
            if ($resCopy !== false) {
1251
                $newProduct->setVar('product_thumb_url', $resCopy);
1252
            }
1253
        }
1254
1255
        // Copie du fichier attaché
1256 View Code Duplication
        if (xoops_trim($originalProduct->getVar('product_attachment')) != '') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1257
            $resCopy = Oledrion_utils::duplicateFile(OLEDRION_ATTACHED_FILES_PATH, $originalProduct->getVar('product_attachment'));
1258
            if ($resCopy !== false) {
1259
                $newProduct->setVar('product_attachment', $resCopy);
1260
            }
1261
        }
1262
1263
        $res = $this->insert($newProduct, true);
1264
        if ($res) {
1265
            $newProductId = $newProduct->getVar('product_id');
1266
            // Copie des fichiers liés
1267
            if ($h_oledrion_files->getProductFilesCount($originalProduct->product_id) > 0) {
1268
                $attachedFiles = array();
0 ignored issues
show
Unused Code introduced by
$attachedFiles 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...
1269
                $attachedFiles = $h_oledrion_files->getProductFiles($originalProduct->product_id);
1270
                if (count($attachedFiles) > 0) {
1271
                    foreach ($attachedFiles as $oneFile) {
1272
                        $newAttachedFile = $oneFile->xoopsClone();
1273
                        $newAttachedFile->setVar('file_product_id', $newProductId);
1274
                        $resCopy = Oledrion_utils::duplicateFile(OLEDRION_ATTACHED_FILES_PATH, $oneFile->getVar('file_filename'));
1275
                        if ($resCopy !== false) {
1276
                            $newAttachedFile->setVar('file_filename', $resCopy);
1277
                        }
1278
                        $newAttachedFile->setNew();
1279
                        $h_oledrion_files->insert($newAttachedFile, true);
1280
                    }
1281
                }
1282
            }
1283
1284
            // Copie des fabricants
1285
            $tblTmp   = array();
0 ignored issues
show
Unused Code introduced by
$tblTmp 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...
1286
            $criteria = new Criteria('pm_product_id', $originalProduct->getVar('product_id'), '=');
1287
            $tblTmp   = $h_oledrion_productsmanu->getObjects($criteria);
1288 View Code Duplication
            foreach ($tblTmp as $productAuthor) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1289
                $newProductAuthor = $productAuthor->xoopsClone();
1290
                $newProductAuthor->setVar('pm_product_id', $newProductId);
1291
                $newProductAuthor->setVar('pm_id', 0);
1292
                $newProductAuthor->setNew();
1293
                $h_oledrion_productsmanu->insert($newProductAuthor, true);
1294
            }
1295
1296
            // Copie des produits relatifs
1297
            $tblTmp   = array();
0 ignored issues
show
Unused Code introduced by
$tblTmp 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...
1298
            $criteria = new Criteria('related_product_id', $originalProduct->getVar('product_id'), '=');
1299
            $tblTmp   = $h_oledrion_related->getObjects($criteria);
1300 View Code Duplication
            foreach ($tblTmp as $related) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1301
                $newRelated = $related->xoopsClone();
1302
                $newRelated->setVar('related_product_id', $newProductId);
1303
                $newRelated->setVar('related_id', 0);
1304
                $newRelated->setNew();
1305
                $h_oledrion_related->insert($newRelated, true);
1306
            }
1307
1308
            // Copie des attributs
1309
            if ($oledrionHandlers->h_oledrion_attributes->getProductAttributesCount($originalProduct->product_id) > 0) {
1310
                $criteria = new Criteria('attribute_product_id', $originalProduct->product_id, '=');
1311
                $tblTmp   = $oledrionHandlers->h_oledrion_attributes->getObjects($criteria);
1312 View Code Duplication
                foreach ($tblTmp as $attribute) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1313
                    $newAttribute = $attribute->xoopsClone();
1314
                    $newAttribute->setVar('attribute_product_id', $newProductId);
1315
                    $newAttribute->setVar('attribute_id', 0);
1316
                    $newAttribute->setNew();
1317
                    $oledrionHandlers->h_oledrion_attributes->insert($newAttribute, true);
1318
                }
1319
            }
1320
1321
            return $newProduct;
1322
        } else {
1323
            return false;
1324
        }
1325
    }
1326
1327
    /**
1328
     * Construit un sélecteur de produit(s) en fonction des paramètres et en tenant compte du nombre total de produits dans la base
1329
     *
1330
     * @todo     : Remplacer les paramètres par un objet paramètre et/ou un tableau
1331
     * @param  Oledrion_parameters $parameters
1332
     * @return object              Retourne soit un objet de type tray <a href='psi_element://XoopsFormElementTray'>XoopsFormElementTray</a> soit un select <a href='psi_element://XoopsFormSelect'>XoopsFormSelect</a>
1333
     * @internal param string $caption Le titre du sélecteur
1334
     * @internal param string $name Le nom du champ qui receuille les produits
1335
     * @internal param mixed $value La valeur sélectionnées
1336
     * @internal param int $size Le nombre d'éléments visibles dans le sélecteur
1337
     * @internal param bool $multiple Indique si c'est un sélecteur multiple ou pas
1338
     * @internal param array $values Les valeurs sélectionnées ou les valeurs qui font le sélecteur
1339
     * @internal param bool $showAll Indique s'il faut voir tous les produits ou pas (pas publiés et en stock)
1340
     * @internal param string $sort Zone de tri
1341
     * @internal param string $order Ordre de tri
1342
     * @internal param string $formName Nom du formulaire
1343
     * @internal param string $description Description à rajouter à la zone
1344
     * @internal param mixed $withNull Option à rajouter en premier
1345
     */
1346
    public function productSelector(Oledrion_parameters $parameters)
1347
    {
1348
        $parameters = $parameters->extend(new Oledrion_parameters(array(
0 ignored issues
show
Documentation introduced by
new \Oledrion_parameters...', 'withNull' => null)) is of type object<Oledrion_parameters>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1349
                                                                      'caption'     => '',
1350
                                                                      'name'        => '',
1351
                                                                      'value'       => null,
1352
                                                                      'size'        => 1,
1353
                                                                      'multiple'    => false,
1354
                                                                      'values'      => null,
1355
                                                                      'showAll'     => true,
1356
                                                                      'sort'        => 'product_title',
1357
                                                                      'order'       => 'ASC',
1358
                                                                      'formName'    => '',
1359
                                                                      'description' => '',
1360
                                                                      'withNull'    => null
1361
                                                                  )));
1362
        static $jqueryIncluded = null;
1363
        require_once XOOPS_ROOT_PATH . '/class/xoopsformloader.php';
1364
        $criteria = new CriteriaCompo();
1365
        $criteria->add(new Criteria('product_id', 0, '<>'));
1366
        if (!$parameters['showAll']) {
1367
            if (Oledrion_utils::getModuleOption('show_unpublished') == 0) { // Ne pas afficher les produits qui ne sont pas publiés
1368
                $criteria->add(new Criteria('product_submitted', time(), '<='));
1369
            }
1370
            if (Oledrion_utils::getModuleOption('nostock_display') == 0) { // Se limiter aux seuls produits encore en stock
1371
                $criteria->add(new Criteria('product_stock', 0, '>'));
1372
            }
1373
        }
1374
        $criteria->setSort($parameters['sort']);
1375
        $criteria->setOrder($parameters['order']);
1376
        $itemsCount = $this->getCount($criteria);
1377
        if ($itemsCount > Oledrion_utils::getModuleOption('max_products')) { // Il faut créer notre propre sélecteur
1378
            if ($parameters['multiple']) {
1379
                if (null === $jqueryIncluded) {
1380
                    $jqueryIncluded = true;
1381
                    global $xoTheme;
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...
1382
                    $xoTheme->addScript('browse.php?Frameworks/jquery/jquery.js');
1383
                }
1384
                Oledrion_utils::callJavascriptFile('select/select.js', false, true);
1385
                $productTray  = new XoopsFormElementTray($parameters['caption'], '');
1386
                $productsList = new XoopsFormSelect('', $parameters['name'], $parameters['values'], $parameters['size'], $parameters['multiple']);
1387
                // Recherche des produits
1388
                $selectedProducts = $this->getList(new Criteria('product_id', '(' . implode(',', $parameters['values']) . ')', 'IN'));
1389
                $productsList->addOptionArray($selectedProducts); // Les valeurs sélectionnées
1390
                $productTray->addElement($productsList);
1391
                $removeButton = new XoopsFormButton('', 'removeProduct', _AM_OLEDRION_REMOVE_SELECTED, 'button');
1392
                if (Oledrion_utils::isX20()) {
1393
                    $removeButton->setExtra(" onclick=\"removeOptionSelected('" . $parameters['name'] . "[]');\"");
1394
                } else {
1395
                    $removeButton->setExtra(" onclick=\"removeOptionSelected('" . $parameters['name'] . "');\"");
1396
                }
1397
                $productTray->addElement($removeButton);
1398
                if (Oledrion_utils::isX20()) {
1399
                    $link = "<a href=\"javascript:openWithSelfMain('" . OLEDRION_ADMIN_URL . 'productsselector.php?mutipleSelect=1&amp;callerName=' . $parameters['name'] . "[]', '', " . OLEDRION_MAX_PRODUCTS_POPUP_WIDTH . ', '
1400
                            . OLEDRION_MAX_PRODUCTS_POPUP_HEIGHT . ");\">" . _AM_OLEDRION_SELECT_OTHER_P . '</a>';
1401
                } else {
1402
                    $link = "<a href=\"javascript:openWithSelfMain('" . OLEDRION_ADMIN_URL . 'productsselector.php?mutipleSelect=1&amp;callerName=' . $parameters['name'] . "', '', " . OLEDRION_MAX_PRODUCTS_POPUP_WIDTH . ', '
1403
                            . OLEDRION_MAX_PRODUCTS_POPUP_HEIGHT . ");\">" . _AM_OLEDRION_SELECT_OTHER_P . '</a>';
1404
                }
1405
                $linkLabel = new xoopsFormLabel('', '<br>' . $link);
1406
                $productTray->addElement($linkLabel);
1407
                echo "<script type=\"text/javascript\">\n";
1408
                echo "jQuery().ready(function($) {\n";
1409
                echo "$(\"#" . $parameters['formName'] . "\").submit( function() {\n";
1410
                echo "  selectAll('" . $parameters['name'] . "', true);\n";
1411
                echo "} );\n";
1412
                echo "});\n";
1413
                echo "</script>\n";
1414
            } else { // Pas de sélection multiple
1415
                $productTray  = new XoopsFormElementTray($parameters['caption'], '');
1416
                $productsList = new XoopsFormSelect('', $parameters['name'], $parameters['value'], $parameters['size'], $parameters['multiple']);
1417
                // Recherche des produits
1418
                if ($parameters['value'] > 0) {
1419
                    $selectedProducts = $this->getList(new Criteria('product_id', $parameters['value'], '='));
1420
                    if (null !== $parameters['withNull']) {
1421
                        $selectedProducts[0] = $parameters['withNull'];
1422
                        ksort($selectedProducts);
1423
                    }
1424
                    $productsList->addOptionArray($selectedProducts); // Les valeurs sélectionnées
1425
                }
1426
                $productTray->addElement($productsList);
1427
                $link      = "<a href=\"javascript:openWithSelfMain('" . OLEDRION_ADMIN_URL . 'productsselector.php?mutipleSelect=0&amp;callerName=' . $parameters['name'] . "', '', " . OLEDRION_MAX_PRODUCTS_POPUP_WIDTH . ', '
1428
                             . OLEDRION_MAX_PRODUCTS_POPUP_HEIGHT . ");\">" . _AM_OLEDRION_SELECT_PRODUCT . '</a>';
1429
                $linkLabel = new xoopsFormLabel('', '<br>' . $link);
1430
                $productTray->addElement($linkLabel);
1431
            }
1432
        } else {
1433
            $productTray = new XoopsFormSelect($parameters['caption'], $parameters['name'], $parameters['value'], $parameters['size'], $parameters['multiple']);
1434
            $products    = $this->getList($criteria);
1435
            $productTray->addOptionArray($products);
1436
        }
1437
1438
        if (trim($parameters['description']) != '') {
1439
            $productTray->setDescription($parameters['description']);
1440
        }
1441
1442
        return $productTray;
1443
    }
1444
}
1445