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

class/oledrion_attributes.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * ****************************************************************************
4
 * oledrion - MODULE FOR XOOPS
5
 * Copyright (c) Hervé Thouzard (http://www.herve-thouzard.com/)
6
 *
7
 * You may not change or alter any portion of this comment or credits
8
 * of supporting developers from this source code or any supporting source code
9
 * which is considered copyrighted (c) material of the original comment or credit authors.
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 *
14
 * @copyright       Hervé Thouzard (http://www.herve-thouzard.com/)
15
 * @license         http://www.fsf.org/copyleft/gpl.html GNU public license
16
 * @package         oledrion
17
 * @author          Hervé Thouzard (http://www.herve-thouzard.com/)
18
 *
19
 * Version :
20
 * ****************************************************************************
21
 */
22
23
/**
24
 * Gestion des options (attributs) de produits
25
 *
26
 * @since 2.3.2009.03.10
27
 */
28
require __DIR__ . '/classheader.php';
29
30
// Les types d'option
31
define('OLEDRION_ATTRIBUTE_RADIO', 1);
32
define('OLEDRION_ATTRIBUTE_CHECKBOX', 2);
33
define('OLEDRION_ATTRIBUTE_SELECT', 3);
34
35
// Le séparateur de données utilisé en interne
36
define('OLEDRION_ATTRIBUTE_SEPARATOR', '|');
37
define('OLEDRION_EMPTY_OPTION', '');
38
39
// Le séparateur de ligne lorsque l'option est un bouton radio ou des cases à cocher
40
define('OLEDRION_ATTRIBUTE_CHECKBOX_WHITE_SPACE', 1);     // Séparateur de ligne = espace blanc
41
define('OLEDRION_ATTRIBUTE_CHECKBOX_NEW_LINE', 2);        // Séparateur de ligne = retour à la ligne
42
43
// Les options par défaut lorsque l'option est une liste déroulante
44
define('OLEDRION_ATTRIBUTE_SELECT_VISIBLE_OPTIONS', 1);    // Valeur par défaut, nombre d'options visibles
45
define('OLEDRION_ATTRIBUTE_SELECT_MULTIPLE', false);       // Valeur par défaut, sélecteur multiple ?
46
47
/**
48
 * Class Oledrion_attributes
49
 */
50
class Oledrion_attributes extends Oledrion_Object
51
{
52
    /**
53
     * constructor
54
     *
55
     * normally, this is called from child classes only
56
     *
57
     * @access public
58
     */
59
    public function __construct()
60
    {
61
        $this->initVar('attribute_id', XOBJ_DTYPE_INT, null, false);
62
        $this->initVar('attribute_weight', XOBJ_DTYPE_INT, null, false);
63
        $this->initVar('attribute_title', XOBJ_DTYPE_TXTBOX, null, false);
64
        $this->initVar('attribute_name', XOBJ_DTYPE_TXTBOX, null, false);
65
        $this->initVar('attribute_type', XOBJ_DTYPE_INT, null, false);
66
        $this->initVar('attribute_mandatory', XOBJ_DTYPE_INT, null, false);
67
        $this->initVar('attribute_names', XOBJ_DTYPE_TXTAREA, null, false);
68
        $this->initVar('attribute_values', XOBJ_DTYPE_TXTAREA, null, false);
69
        $this->initVar('attribute_prices', XOBJ_DTYPE_TXTAREA, null, false);
70
        $this->initVar('attribute_stocks', XOBJ_DTYPE_TXTAREA, null, false);
71
        $this->initVar('attribute_product_id', XOBJ_DTYPE_INT, null, false);
72
        $this->initVar('attribute_default_value', XOBJ_DTYPE_TXTBOX, null, false);
73
        $this->initVar('attribute_option1', XOBJ_DTYPE_INT, null, false);
74
        $this->initVar('attribute_option2', XOBJ_DTYPE_INT, null, false);
75
    }
76
77
    /**
78
     * Indique si l'attribut courant a une valeur par défaut
79
     *
80
     * @return boolean
81
     * @since 2.3.2009.03.20
82
     */
83
    public function hasDefaultValue()
84
    {
85
        if (xoops_trim($this->getVar('attribute_default_value')) != '') {
86
            return true;
87
        }
88
89
        return false;
90
    }
91
92
    /**
93
     * Retourne le nom du champs tel qu'il est construit dans le formulaire sur la fiche produit
94
     *
95
     * @return string
96
     */
97
    public function getAttributeNameInForm()
98
    {
99
        return $this->getVar('attribute_name') . '_' . $this->getVar('attribute_id');
100
    }
101
102
    /**
103
     * Retourne une option de l'attribut
104
     *
105
     * @param  string $valueToGet
106
     * @param  string $format
107
     * @return array
108
     * @since 2.3.2009.03.11
109
     */
110 View Code Duplication
    public function getOption($valueToGet, $format = 'e')
111
    {
112
        $names = array();
113
        if (xoops_trim($this->getVar($valueToGet, $format)) != '') {
114
            $names = explode(OLEDRION_ATTRIBUTE_SEPARATOR, $this->getVar($valueToGet, $format));
115
        }
116
117
        return $names;
118
    }
119
120
    /**
121
     * Retourne le nombre d'options de l'attribut courant
122
     *
123
     * @return integer
124
     * @since 2.3.2009.03.12
125
     */
126
    public function getOptionsCount()
127
    {
128
        $names = explode(OLEDRION_ATTRIBUTE_SEPARATOR, $this->getVar('attribute_names', 's'));
129
130
        return count($names);
131
    }
132
133
    /**
134
     * Ajout d'une option à l'attribut (soit une option vide soit une option valorisée)
135
     *
136
     * @param  string $name
137
     * @param  string $value
138
     * @param  string $price
139
     * @param  string $stock
140
     * @return boolean
141
     * @since 2.3.2009.03.16
142
     */
143
    private function appendOption($name, $value, $price = '', $stock = '')
144
    {
145
        $names  = $values = $prices = $stocks = array();
146
        $format = 'e';
147
        $names  = $this->getOption('attribute_names', $format);
148
        $values = $this->getOption('attribute_values', $format);
149
        if (Oledrion_utils::getModuleOption('use_price')) {
150
            $prices = $this->getOption('attribute_prices', $format);
151
        }
152
        if (Oledrion_utils::getModuleOption('attributes_stocks')) {
153
            $stocks = $this->getOption('attribute_stocks', $format);
154
        }
155
        $names[]  = $name;
156
        $values[] = $value;
157
        if (Oledrion_utils::getModuleOption('use_price')) {
158
            $prices[] = $price;
159
        }
160
        if (Oledrion_utils::getModuleOption('attributes_stocks')) {
161
            $stocks[] = $stock;
162
        }
163
        $this->setVar('attribute_names', implode(OLEDRION_ATTRIBUTE_SEPARATOR, $names));
164
        $this->setVar('attribute_values', implode(OLEDRION_ATTRIBUTE_SEPARATOR, $values));
165
        if (Oledrion_utils::getModuleOption('use_price')) {
166
            $this->setVar('attribute_prices', implode(OLEDRION_ATTRIBUTE_SEPARATOR, $prices));
167
        }
168
        if (Oledrion_utils::getModuleOption('attributes_stocks')) {
169
            $this->setVar('attribute_stocks', implode(OLEDRION_ATTRIBUTE_SEPARATOR, $stocks));
170
        }
171
172
        return true;
173
    }
174
175
    /**
176
     * Ajoute une option vide à la fin (avec des valeurs par défaut)
177
     *
178
     * @return boolean
179
     * @since 2.3.2009.03.12
180
     */
181
    public function addEmptyOption()
182
    {
183
        return $this->appendOption(_AM_OLEDRION_ATTRIBUTE_DEF_VALUE, _AM_OLEDRION_ATTRIBUTE_DEF_VALUE, _AM_OLEDRION_ATTRIBUTE_DEF_AMOUNT, _AM_OLEDRION_ATTRIBUTE_DEF_AMOUNT);
184
    }
185
186
    /**
187
     * Ajoute une nouvelle option à l'attribut
188
     *
189
     * @param  string $name
190
     * @param  string $value
191
     * @param  string $price
192
     * @param  string $stock
193
     * @return boolean
194
     * @since 2.3.2009.03.16
195
     */
196
    public function addOption($name, $value, $price = '', $stock = '')
197
    {
198
        return $this->appendOption($name, $value, $price, $stock);
199
    }
200
201
    /**
202
     * Réinitialisation des options de l'attribut
203
     *
204
     * @return boolean True
205
     * @since 2.3.2009.03.10
206
     */
207
    public function resetOptions()
208
    {
209
        $this->setVar('attribute_names', OLEDRION_EMPTY_OPTION);
210
        $this->setVar('attribute_values', OLEDRION_EMPTY_OPTION);
211
        if (Oledrion_utils::getModuleOption('use_price')) {
212
            $this->setVar('attribute_prices', OLEDRION_EMPTY_OPTION);
213
        }
214
        if (Oledrion_utils::getModuleOption('attributes_stocks')) {
215
            $this->setVar('attribute_stocks', OLEDRION_EMPTY_OPTION);
216
        }
217
218
        return true;
219
    }
220
221
    /**
222
     * Renseigne une option
223
     *
224
     * @param  integer $optionNumber (de 0 à N)
225
     * @param  string  $name         Valeur pour name
226
     * @param  string  $value        Valeur pour value
227
     * @param  string  $price        Valeur pour prix
228
     * @param  string  $stock        Valeur pour stock
229
     * @return boolean True si la mise à jour s'est faite sinon false
230
     * @since 2.3.2009.03.10
231
     */
232
    public function setOptionValue($optionNumber, $name, $value, $price = '', $stock = '')
233
    {
234
        $optionNumber = (int)$optionNumber;
235
        if ($optionNumber < 0 || $optionNumber > $this->getOptionsCount()) {
236
            return false;
237
        }
238
        $names  = $values = $prices = $stocks = array();
239
        $format = 'e';
240
        $names  = $this->getOption('attribute_names', $format);
241
        $values = $this->getOption('attribute_values', $format);
242
        if (Oledrion_utils::getModuleOption('use_price')) {
243
            $prices = $this->getOption('attribute_prices', $format);
244
        }
245
        if (Oledrion_utils::getModuleOption('attributes_stocks')) {
246
            $stocks = $this->getOption('attribute_stocks', $format);
247
        }
248
        if (isset($names[$optionNumber])) {
249
            $names[$optionNumber] = $name;
250
        }
251
        if (isset($values[$optionNumber])) {
252
            $values[$optionNumber] = $value;
253
        }
254
        if (Oledrion_utils::getModuleOption('use_price')) {
255
            if (isset($prices[$optionNumber])) {
256
                $prices[$optionNumber] = $price;
257
            }
258
        }
259
        if (Oledrion_utils::getModuleOption('attributes_stocks')) {
260
            if (isset($stocks[$optionNumber])) {
261
                $stocks[$optionNumber] = $stock;
262
            }
263
        }
264
        $this->setVar('attribute_names', implode(OLEDRION_ATTRIBUTE_SEPARATOR, $names));
265
        $this->setVar('attribute_values', implode(OLEDRION_ATTRIBUTE_SEPARATOR, $values));
266
        if (Oledrion_utils::getModuleOption('use_price')) {
267
            $this->setVar('attribute_prices', implode(OLEDRION_ATTRIBUTE_SEPARATOR, $prices));
268
        }
269
        if (Oledrion_utils::getModuleOption('attributes_stocks')) {
270
            $this->setVar('attribute_stocks', implode(OLEDRION_ATTRIBUTE_SEPARATOR, $stocks));
271
        }
272
273
        return true;
274
    }
275
276
    /**
277
     * Echange deux contenus dans un tableau
278
     *
279
     * @param  array   $array
280
     * @param  integer $from
281
     * @param  integer $to
282
     * @return void
283
     * @since 2.3.2009.03.10
284
     */
285
    private function swapValues(&$array, $from, $to)
286
    {
287
        $tempValue    = $array[$to];
288
        $array[$to]   = $array[$from];
289
        $array[$from] = $tempValue;
290
    }
291
292
    /**
293
     * Fonction interne chargée du déplacement d'une option soit vers le haut soit vers le bas
294
     *
295
     * @param  integer $optionNumber
296
     * @param  integer $upDown 1=Up, 2=Down
297
     * @return boolean
298
     * @since 2.3.2009.03.10
299
     */
300
    private function moveOption($optionNumber, $upDown)
301
    {
302
        $optionNumber = (int)$optionNumber;
303
        if ($upDown == 1) {    // Up
304
            $newPosition = $optionNumber - 1;
305
        } else {    // Down
306
            $newPosition = $optionNumber + 1;
307
        }
308
        if ($optionNumber < 0 || $optionNumber > $this->getOptionsCount()) {
309
            return false;
310
        }
311
        $format = 'e';
312
        $names  = $this->getOption('attribute_names', $format);
313
        $values = $this->getOption('attribute_values', $format);
314
        if (Oledrion_utils::getModuleOption('use_price')) {
315
            $prices = $this->getOption('attribute_prices', $format);
316
        }
317
        if (Oledrion_utils::getModuleOption('attributes_stocks')) {
318
            $stocks = $this->getOption('attribute_stocks', $format);
319
        }
320
        if (isset($names[$optionNumber])) {
321
            $this->swapValues($names, $optionNumber, $newPosition);
322
        }
323
        if (isset($values[$optionNumber])) {
324
            $this->swapValues($values, $optionNumber, $newPosition);
325
        }
326
        if (Oledrion_utils::getModuleOption('use_price')) {
327
            if (isset($prices[$optionNumber])) {
328
                $this->swapValues($prices, $optionNumber, $newPosition);
329
            }
330
        }
331
        if (Oledrion_utils::getModuleOption('attributes_stocks')) {
332
            if (isset($stocks[$optionNumber])) {
333
                $this->swapValues($stocks, $optionNumber, $newPosition);
334
            }
335
        }
336
        $this->setVar('attribute_names', implode(OLEDRION_ATTRIBUTE_SEPARATOR, $names));
337
        $this->setVar('attribute_values', implode(OLEDRION_ATTRIBUTE_SEPARATOR, $values));
338
        if (Oledrion_utils::getModuleOption('use_price')) {
339
            $this->setVar('attribute_prices', implode(OLEDRION_ATTRIBUTE_SEPARATOR, $prices));
340
        }
341
        if (Oledrion_utils::getModuleOption('attributes_stocks')) {
342
            $this->setVar('attribute_stocks', implode(OLEDRION_ATTRIBUTE_SEPARATOR, $stocks));
343
        }
344
345
        return true;
346
    }
347
348
    /**
349
     * Déplace une option vers le haut
350
     *
351
     * @param  integer $optionNumber
352
     * @return boolean
353
     * @since 2.3.2009.03.10
354
     */
355
    public function moveOptionUp($optionNumber)
356
    {
357
        return $this->moveOption($optionNumber, 1);
358
    }
359
360
    /**
361
     * Déplace une option vers le bas
362
     *
363
     * @param  integer $optionNumber
364
     * @return boolean
365
     * @since 2.3.2009.03.10
366
     */
367
    public function moveOptionDown($optionNumber)
368
    {
369
        return $this->moveOption($optionNumber, 2);
370
    }
371
372
    /**
373
     * Supprime une option de l'attribut
374
     *
375
     * @param  integer $optionNumber (de 0 à n)
376
     * @return boolean false si l'indice est hors borne sinon true
377
     * @since 2.3.2009.03.12
378
     */
379
    public function deleteOption($optionNumber)
380
    {
381
        $optionNumber = (int)$optionNumber;
382
        if ($optionNumber < 0 || $optionNumber > $this->getOptionsCount()) {
383
            return false;
384
        }
385
        $format = 'e';
386
        $names  = $this->getOption('attribute_names', $format);
387
        $values = $this->getOption('attribute_values', $format);
388
        if (Oledrion_utils::getModuleOption('use_price')) {
389
            $prices = $this->getOption('attribute_prices', $format);
390
        }
391
        if (Oledrion_utils::getModuleOption('attributes_stocks')) {
392
            $stocks = $this->getOption('attribute_stocks', $format);
393
        }
394
        if (isset($names[$optionNumber])) {
395
            unset($names[$optionNumber]);
396
        }
397
        if (isset($values[$optionNumber])) {
398
            unset($values[$optionNumber]);
399
        }
400
        if (Oledrion_utils::getModuleOption('use_price')) {
401
            if (isset($prices[$optionNumber])) {
402
                unset($prices[$optionNumber]);
403
            }
404
        }
405
        if (Oledrion_utils::getModuleOption('attributes_stocks')) {
406
            if (isset($stocks[$optionNumber])) {
407
                unset($stocks[$optionNumber]);
408
            }
409
        }
410
        $this->setVar('attribute_names', implode(OLEDRION_ATTRIBUTE_SEPARATOR, $names));
411
        $this->setVar('attribute_values', implode(OLEDRION_ATTRIBUTE_SEPARATOR, $values));
412
        if (Oledrion_utils::getModuleOption('use_price')) {
413
            $this->setVar('attribute_prices', implode(OLEDRION_ATTRIBUTE_SEPARATOR, $prices));
414
        }
415
        if (Oledrion_utils::getModuleOption('attributes_stocks')) {
416
            $this->setVar('attribute_stocks', implode(OLEDRION_ATTRIBUTE_SEPARATOR, $stocks));
417
        }
418
419
        return true;
420
    }
421
422
    /**
423
     * Retourne le prix de l'attribut par défaut
424
     *
425
     * @param  string $format
426
     * @return float
0 ignored issues
show
Should the return type not be double|integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
427
     * @since 2.3.2009.03.19
428
     */
429
    public function getDefaultAttributePrice($format = 'e')
430
    {
431
        $defaultValue = xoops_trim($this->getVar('attribute_default_value', 'e'));
432
        if ($defaultValue != '') {    // Il y a une option par défaut donc un prix
433
            $values  = $this->getOption('attribute_values', $format);
434
            $prices  = $this->getOption('attribute_prices', $format);
435
            $counter = 0;
436
            if (count($values) > 0) {
437
                foreach ($values as $value) {
438
                    if (xoops_trim($value) == $defaultValue) {
439
                        if (isset($prices[$counter])) {
440
                            return (float)$prices[$counter];
441
                        } else {
442
                            return 0;
443
                        }
444
                    }
445
                    ++$counter;
446
                }
447
            }
448
        }
449
450
        return 0;
451
    }
452
453
    /**
454
     * Retourne la valeur par défaut de l'attribut courant
455
     *
456
     * @param  string $format
457
     * @return string
458
     * @since 2.3.2009.03.20
459
     */
460
    public function getAttributeDefaultValue($format = 'e')
461
    {
462
        return xoops_trim($this->getVar('attribute_default_value', $format));
463
    }
464
465
    /**
466
     * Retourne une liste combinée des options de l'attribut
467
     *
468
     * @param  string                   $format             Format dans lequel renvoyer les données
469
     * @param  boolean                  $withFormatedPrices Faut il retourner les prix formatés ?
470
     * @param  object|oledrion_products $product            Le produit de travail
0 ignored issues
show
Should the type for parameter $product not be null|Oledrion_products?

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

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

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

Loading history...
471
     * @return array
472
     * @since 2.3.2009.03.11
473
     */
474
    public function getAttributeOptions($format = 's', $withFormatedPrices = false, Oledrion_products $product = null)
475
    {
476
        $ret     = array();
477
        $counter = 0;
478
        if (null !== $product) {
479
            $vat_id = $product->getVar('product_vat_id');
480
        }
481
        $names  = $this->getOption('attribute_names', $format);
482
        $values = $this->getOption('attribute_values', $format);
483
        if (Oledrion_utils::getModuleOption('use_price')) {
484
            $prices = $this->getOption('attribute_prices', $format);
485
        }
486
        if (Oledrion_utils::getModuleOption('attributes_stocks')) {
487
            $stocks = $this->getOption('attribute_stocks', $format);
488
        }
489
490
        if ($withFormatedPrices) {
491
            $oledrion_Currency = Oledrion_Currency::getInstance();
492
        }
493
        if (count($names) > 0) {
494
            foreach ($names as $key => $name) {
495
                $price = $stock = 0;
496
                if (Oledrion_utils::getModuleOption('use_price')) {
497
                    $price = $prices[$key];
498
                    if ($withFormatedPrices) {
499
                        $priceFormated    = $oledrion_Currency->amountForDisplay($price);
500
                        $priceTtc         = Oledrion_utils::getAmountWithVat($price, $vat_id);
501
                        $priceTtcFormated = $oledrion_Currency->amountForDisplay($priceTtc);
502
                        $vat              = $priceTtc - $price;
503
                        $vatFormated      = $oledrion_Currency->amountForDisplay($vat);
504
                    }
505
                }
506
                if (Oledrion_utils::getModuleOption('attributes_stocks')) {
507
                    $stock = $stocks[$key];
508
                }
509
                if (!$withFormatedPrices) {
510
                    $ret[] = array('name' => $name, 'value' => $values[$key], 'price' => $price, 'stock' => $stock);
511
                } else {
512
                    $ret[] = array(
513
                        'name'             => $name,
514
                        'value'            => $values[$key],
515
                        'price'            => $price,
516
                        'priceFormated'    => $priceFormated,
517
                        'priceTTC'         => $priceTtc,
518
                        'priceTTCFormated' => $priceTtcFormated,
519
                        'vat'              => $vat,
520
                        'vatFormated'      => $vatFormated,
521
                        'counter'          => $counter,
522
                        'stock'            => $stock
523
                    );
524
                }
525
                ++$counter;
526
            }
527
        }
528
529
        return $ret;
530
    }
531
532
    /**
533
     * Retourne la liste des types d'attributs
534
     *
535
     * @return array
536
     * @since 2.3.2009.03.10
537
     */
538
    public function getTypesList()
539
    {
540
        $attributeTypeName = array(
541
            OLEDRION_ATTRIBUTE_RADIO    => _AM_OLEDRION_TYPE_RADIO,
542
            OLEDRION_ATTRIBUTE_CHECKBOX => _AM_OLEDRION_TYPE_CHECKBOX,
543
            OLEDRION_ATTRIBUTE_SELECT   => _AM_OLEDRION_TYPE_LIST
544
        );
545
546
        return $attributeTypeName;
547
    }
548
549
    /**
550
     * Retourne le type de l'attribut courant (son libellé)
551
     *
552
     * @return mixed Soit le type de l'attribut soit null;
553
     * @since 2.3.2009.03.10
554
     */
555
    public function getTypeName()
556
    {
557
        $attributeTypeName = $this->getTypesList();
558
        if (isset($attributeTypeName[$this->getVar('attribute_type')])) {
559
            return $attributeTypeName[$this->getVar('attribute_type')];
560
        } else {
561
            return null;
562
        }
563
    }
564
565
    /**
566
     * Retourne le prix d'une option en fonction de son nom
567
     *
568
     * @param  string $optionName
569
     * @return float
570
     */
571 View Code Duplication
    public function getOptionPriceFromValue($optionName)
572
    {
573
        $ret     = 0;
574
        $format  = 's';
575
        $counter = 0;
576
        $values  = $this->getOption('attribute_values', $format);
577
        $prices  = $this->getOption('attribute_prices', $format);
578
        foreach ($values as $value) {
579
            if (xoops_trim($value) == $optionName) {
580
                if (isset($prices[$counter])) {
581
                    return (float)$prices[$counter];
582
                }
583
            }
584
            ++$counter;
585
        }
586
587
        return $ret;
588
    }
589
590
    /**
591
     * Retourne le libellé d'une option en fonction de son nom
592
     *
593
     * @param  string $optionName
594
     * @return string
595
     */
596 View Code Duplication
    public function getOptionNameFromValue($optionName)
597
    {
598
        $ret     = '';
599
        $format  = 's';
600
        $counter = 0;
601
        $values  = $this->getOption('attribute_values', $format);
602
        $names   = $this->getOption('attribute_names', $format);
603
        foreach ($values as $value) {
604
            if (xoops_trim($value) == $optionName) {
605
                if (isset($names[$counter])) {
606
                    return $names[$counter];
607
                }
608
            }
609
            ++$counter;
610
        }
611
612
        return $ret;
613
    }
614
615
    /**
616
     * Création du code html de l'attribut
617
     *
618
     * On utilise le contenu de templates html (réalisés en Smarty) pour créer le contenu de l'attribut
619
     * Templates utilisés (selon le type d'attribut) :
620
     *      oledrion_attribute_checkbox.html
621
     *      oledrion_attribute_radio.html
622
     *      oledrion_attribute_select.html
623
     *
624
     * @param  object|oledrion_products $product Le produit de "travail"
625
     * @return string                   Le contenu html
626
     * @since 2.3.2009.03.16
627
     */
628
    public function render(Oledrion_products $product)
629
    {
630
        include_once XOOPS_ROOT_PATH . '/class/template.php';
631
        $template = new XoopsTpl();
632
633
        $options      = array();
634
        $ret          = $templateName = '';
635
        $elementName  = $this->getVar('attribute_name', 'e');
636
        $elementTitle = $this->getVar('attribute_title');
637
        $option1      = $this->getVar('attribute_option1');
638
        $option2      = $this->getVar('attribute_option2');
639
640
        $handlers = OledrionHandler::getInstance();
641
        $isInCart = $handlers->h_oledrion_caddy->isInCart($product->getVar('product_id'));
642
        if ($isInCart === false) {    // Le produit n'est pas dans le panier, on prend la valeur par défaut
643
            $defaultValue = array($this->getVar('attribute_default_value'));
644
        } else {    // Le produit est dans le panier, on va chercher les options qui sont sélectionnées
645
            $Productattributes = $handlers->h_oledrion_caddy->getProductAttributesFromCart($product->getVar('product_id'));
646
            if (isset($Productattributes[$this->getVar('attribute_id')])) {
647
                $defaultValue = $Productattributes[$this->getVar('attribute_id')];
648
            } else {    // On prend la valeur par défaut
649
                if ($this->attribute_type == OLEDRION_ATTRIBUTE_RADIO) {    // Pour les boutons radio, il ne peut y avoir qu'un élément de sélectionné
650
                    $defaultValue = $this->getVar('attribute_default_value');
651
                } else {
652
                    $defaultValue = array($this->getVar('attribute_default_value'));
653
                }
654
            }
655
            if (!is_array($defaultValue)) {
656
                $defaultValue = array($defaultValue);
657
            }
658
            $newDefaultValue = array();
659
            foreach ($defaultValue as $oneValue) {
660
                $newDefaultValue[] = Oledrion_utils::getName($oneValue);
661
            }
662
            $defaultValue = $newDefaultValue;
663
        }
664
        $options = $this->getAttributeOptions('s', true, $product);
665
666
        // Les valeurs communes
667
        $template->assign('options', $options);
668
        $template->assign('attributeTitle', $elementTitle);
669
        $template->assign('defaultValue', $defaultValue);
670
        $template->assign('attributeName', $this->getVar('attribute_title'));
671
        $template->assign('name', $elementName);
672
        $template->assign('attribute_id', $this->getVar('attribute_id'));
673
        $template->assign('attribute_mandatory', (bool)$this->getVar('attribute_mandatory'));
674
675
        switch ($this->getVar('attribute_type')) {
676
            case OLEDRION_ATTRIBUTE_SELECT:        // Liste déroulante
677
                $templateName = 'oledrion_attribute_select.tpl';
678
                $multiple     = '';
679
                if ($option2 == 1) {    // La sélection multiple est autorisée
680
                    $multiple = "multiple='multiple' ";
681
                }
682
                $template->assign('multiple', $multiple);
683
                $template->assign('size', $option1);
684
685
                break;
686
687 View Code Duplication
            case OLEDRION_ATTRIBUTE_CHECKBOX:      // Cases à cocher
688
                $templateName = 'oledrion_attribute_checkbox.tpl';
689
                $delimiter    = '';
690
                if ($option1 == OLEDRION_ATTRIBUTE_CHECKBOX_WHITE_SPACE) {
691
                    $delimiter = ' ';
692
                } else {
693
                    $delimiter = '<br>';
694
                }
695
                $template->assign('delimiter', $delimiter);
696
                break;
697
698 View Code Duplication
            case OLEDRION_ATTRIBUTE_RADIO:         // Boutons radio
699
                $templateName = 'oledrion_attribute_radio.tpl';
700
                $delimiter    = '';
701
                if ($option1 == OLEDRION_ATTRIBUTE_CHECKBOX_WHITE_SPACE) {
702
                    $delimiter = ' ';
703
                } else {
704
                    $delimiter = '<br>';
705
                }
706
                $template->assign('delimiter', $delimiter);
707
                break;
708
        }
709
        if ($templateName != '') {
710
            $ret = $template->fetch('db:' . $templateName);
711
        }
712
713
        return $ret;
714
    }
715
}
716
717
/**
718
 * Class OledrionOledrion_attributesHandler
719
 */
720
class OledrionOledrion_attributesHandler extends Oledrion_XoopsPersistableObjectHandler
721
{
722
    /**
723
     * OledrionOledrion_attributesHandler constructor.
724
     * @param XoopsDatabase|null  $db
725
     */
726
    public function __construct(XoopsDatabase $db)
727
    {    //                             Table               Classe                  Id
728
        parent::__construct($db, 'oledrion_attributes', 'oledrion_attributes', 'attribute_id');
729
    }
730
731
    /**
732
     * Supprime tous les attributs d'un produit
733
     *
734
     * @param  integer $attribute_product_id
735
     * @return boolean Le résultat de la suppression
736
     * @since 2.3.2009.03.16
737
     */
738
    public function deleteProductAttributes($attribute_product_id)
739
    {
740
        $attribute_product_id = (int)$attribute_product_id;
741
742
        return $this->deleteAll(new Criteria('attribute_product_id', $attribute_product_id, '='));
743
    }
744
745
    /**
746
     * Retourne le nombre total d'attributs d'un produit (qu'ils soient obligatoires ou pas)
747
     *
748
     * @param  integer $attribute_product_id
749
     * @return integer
750
     * @since 2.3.2009.03.16
751
     */
752
    public function getProductAttributesCount($attribute_product_id)
753
    {
754
        return $this->getCount(new Criteria('attribute_product_id', $attribute_product_id, '='));
755
    }
756
757
    /**
758
     * Retourne la liste des attributs d'un produit
759
     *
760
     * @param  integer $product_id Le produit concerné
761
     * @param  null    $attributesIds
762
     * @return array
763
     */
764
    public function getProductsAttributesList($product_id, $attributesIds = null)
765
    {
766
        $ret      = array();
767
        $criteria = new CriteriaCompo();
768 View Code Duplication
        if (is_array($product_id)) {
0 ignored issues
show
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...
769
            $criteria->add(new Criteria('attribute_product_id', '(' . implode(',', $product_id) . ')', 'IN'));
770
        } else {
771
            $criteria->add(new Criteria('attribute_product_id', $product_id, '='));
772
        }
773
        if (is_array($attributesIds) && count($attributesIds) > 0) {
774
            $criteria->add(new Criteria('attribute_id', '(' . implode(',', array_keys($attributesIds)) . ')', 'IN'));
775
        }
776
        $criteria->setSort('attribute_weight, attribute_title');    // L'ajout du titre dans le tri permet de trier même lorsque le poids n'est pas valorisé
777
        $ret = $this->getObjects($criteria);
778
779
        return $ret;
780
    }
781
782
    /**
783
     * Construction de la liste des attributs d'un produit
784
     *
785
     * @param  object|oledrion_products $product              Le produit concerné
786
     * @param  integer                  $mandatoryFieldsCount Retourne le nombre d'options requises
787
     * @return array                    Les options construites en html
788
     * @since 2.3.2009.03.16
789
     */
790
    public function constructHtmlProductAttributes(Oledrion_products $product, &$mandatoryFieldsCount = 0)
791
    {
792
        $attributes = $ret = array();
793
        $attributes = $this->getProductsAttributesList($product->getVar('product_id'));
794
        if (count($attributes) == 0) {
795
            return $ret;
796
        }
797
        foreach ($attributes as $attribute) {
798
            if ((bool)$attribute->getVar('attribute_mandatory')) {
799
                ++$mandatoryFieldsCount;
800
            }
801
            $ret[] = $attribute->render($product);
802
        }
803
804
        return $ret;
805
    }
806
807
    /**
808
     * Retourne le montant initial des options d'un produit
809
     *
810
     * @param  oledrion_products $product
811
     * @return float
812
     */
813
    public function getInitialOptionsPrice(Oledrion_products $product)
814
    {
815
        $ret        = 0;
816
        $attributes = array();
817
        $attributes = $this->getProductsAttributesList($product->getVar('product_id'));
818
        foreach ($attributes as $attribute) {
819
            $ret += $attribute->getDefaultAttributePrice();
820
        }
821
822
        return $ret;
823
    }
824
825
    /**
826
     * Clonage d'un attribut
827
     *
828
     * @param  Oledrion_attributes $originalAttribute
829
     * @return mixed               Soit le nouvel attribut si tout a bien marché sinon false
830
     * @internal param Oledrion_attributes $attribute L'attribute à cloner
831
     * @since    2.3.2009.03.16
832
     */
833
    public function cloneAttribute(Oledrion_attributes $originalAttribute)
834
    {
835
        $newAttribute =& $originalAttribute->xoopsClone();
836 View Code Duplication
        if (OLEDRION_DUPLICATED_PLACE === 'right') {
837
            $newAttribute->setVar('attribute_title', $originalAttribute->getVar('attribute_title') . ' ' . _AM_OLEDRION_DUPLICATED);
838
        } else {
839
            $newAttribute->setVar('attribute_title', _AM_OLEDRION_DUPLICATED . ' ' . $originalAttribute->getVar('attribute_title'));
840
        }
841
        $newAttribute->setVar('attribute_id', 0);
842
        $newAttribute->setNew();
843
844
        $res = $this->insert($newAttribute, true);
845
        if ($res) {
846
            return $newAttribute;
847
        } else {
848
            return false;
849
        }
850
    }
851
852
    /**
853
     * Retourne la liste des produits utilisés dans la table (liste unique)
854
     *
855
     * @return array Value = id produits (uniques)
856
     * @since 2.3.2009.03.16
857
     */
858
    public function getDistinctsProductsIds()
859
    {
860
        $ret = array();
861
        $ret = $this->getDistincts('attribute_product_id');
862
        if (count($ret) > 0) {
863
            return array_values($ret);
864
        }
865
866
        return $ret;
867
    }
868
869
    /**
870
     * Suppression d'un attribut (et de ce qui y est rattaché)
871
     *
872
     * @param  oledrion_attributes $attribute
873
     * @return boolean
874
     * @since 2.3.2009.03.17
875
     */
876
    public function deleteAttribute(Oledrion_attributes $attribute)
877
    {
878
        return $this->delete($attribute, true);
879
        // TODO: Supprimer dans les attributs paniers
880
    }
881
882
    /**
883
     * Retourne le nombre d'attributs obligatoires d'un produit
884
     *
885
     * @param  oledrion_products $product
886
     * @return integer
887
     * @since 2.3.2009.03.20
888
     */
889
    public function getProductMandatoryAttributesCount(Oledrion_products $product)
890
    {
891
        $criteria = new CriteriaCompo();
892
        $criteria->add(new Criteria('attribute_product_id', $product->getVar('attribute_product_id'), '='));
893
        $criteria->add(new Criteria('attribute_mandatory', 1, '='));
894
895
        return $this->getCount($criteria);
896
    }
897
898
    /**
899
     * Retourne le nom des champs (représentant les attributs) obligatoires que l'on devrait trouver suite à une sélection de produit
900
     *
901
     * @param  oledrion_products $product
902
     * @return array             objets des type oledrion_attributes
903
     */
904 View Code Duplication
    public function getProductMandatoryFieldsList(Oledrion_products $product)
905
    {
906
        $criteria = new CriteriaCompo();
907
        $criteria->add(new Criteria('attribute_product_id', $product->getVar('attribute_product_id'), '='));
908
        $criteria->add(new Criteria('attribute_mandatory', 1, '='));
909
910
        return $this->getObjects($criteria);
911
    }
912
913
    /**
914
     * Calcul le prix HT des options sélectionnées pour un produit
915
     *
916
     * @param  array   $choosenAttributes [clé] = attribute_id, [value] = array(valueId1, valueId2 ...)
917
     * @param  integer $product_vat_id    L'ID de TVA du produit
918
     * @param  array   $descriptions      Tableau valorisé par la méthode [clé] = Id attribut [valeur] = array('attribute_title', array('attribute_names', 'attribute_prices'))
919
     * @return float
920
     * @since 2.3.2009.03.21
921
     */
922
    public function getProductOptionsPrice($choosenAttributes, $product_vat_id, &$descriptions = null)
923
    {
924
        static $vats = array();
925
        if (is_array($vats) && isset($vats[$product_vat_id])) {
926
            $vat_rate = $vats[$product_vat_id];
927
        } else {
928
            $vat = null;
929
            $vat = OledrionHandler::getInstance()->h_oledrion_vat->get($product_vat_id);
930
            if (is_object($vat)) {
931
                $vats[$product_vat_id] = $vat_rate = $vat->getVar('vat_rate', 'n');
932
            }
933
        }
934
        $ret           = 0;
935
        $attributesIds = $attributes = array();
936
        if (!is_array($choosenAttributes) || count($choosenAttributes) == 0) {
937
            return $ret;
938
        }
939
        $attributesIds = array_keys($choosenAttributes);
940
941
        $attributes = $this->getItemsFromIds($attributesIds);
942
        if (count($attributes) == 0) {
943
            return $ret;
944
        }
945
        $oledrion_Currency = Oledrion_Currency::getInstance();
946
947
        foreach ($choosenAttributes as $userAttributeId => $userAttributeValues) {
948
            if (isset($attributes[$userAttributeId])) {
949
                $attribute           = $attributes[$userAttributeId];
950
                $dataForDescriptions = array();
951
                $optionDescription   = '';
952
                if (is_array($userAttributeValues) && count($userAttributeValues) > 0) {
953
                    foreach ($userAttributeValues as $option) {
954
                        $optionName            = Oledrion_utils::getName($option);
955
                        $price                 = $attribute->getOptionPriceFromValue($optionName);
956
                        $optionDescription     = $attribute->getOptionNameFromValue($optionName);
957
                        $vatAmount             = Oledrion_utils::getVAT($price, $vat_rate);
958
                        $ttc                   = $price + $vatAmount;
959
                        $vatAmountFormated     = $oledrion_Currency->amountForDisplay($vatAmount);
960
                        $htFormated            = $oledrion_Currency->amountForDisplay($price);
961
                        $ttcFormated           = $oledrion_Currency->amountForDisplay($ttc);
962
                        $dataForDescriptions[] = array(
963
                            'option_name'              => $optionDescription,
964
                            'option_value'             => $optionName,
965
                            'option_price'             => $price,
966
                            'option_vat'               => $vatAmount,
967
                            'option_ttc'               => $ttc,
968
                            'option_price_ht_formated' => $htFormated,
969
                            'option_vat_formated'      => $vatAmountFormated,
970
                            'option_ttc_formated'      => $ttcFormated
971
                        );
972
                        $ret += $price;    // Total de toutes les options
973
                    }
974
                } else {
975
                    $optionName            = Oledrion_utils::getName($userAttributeValues);
976
                    $price                 = $attribute->getOptionPriceFromValue($optionName);
977
                    $optionDescription     = $attribute->getOptionNameFromValue($optionName);
978
                    $vatAmount             = Oledrion_utils::getVAT($price, $vat_rate);
979
                    $ttc                   = $price + $vatAmount;
980
                    $vatAmountFormated     = $oledrion_Currency->amountForDisplay($vatAmount);
981
                    $htFormated            = $oledrion_Currency->amountForDisplay($price);
982
                    $ttcFormated           = $oledrion_Currency->amountForDisplay($ttc);
983
                    $dataForDescriptions[] = array(
984
                        'option_name'              => $optionDescription,
985
                        'option_value'             => $optionName,
986
                        'option_price'             => $price,
987
                        'option_vat'               => $vatAmount,
988
                        'option_ttc'               => $ttc,
989
                        'option_price_ht_formated' => $htFormated,
990
                        'option_vat_formated'      => $vatAmountFormated,
991
                        'option_ttc_formated'      => $ttcFormated
992
                    );
993
                    $ret += $price;    // Total de toutes les options
994
                }
995
                if (is_array($descriptions)) {
996
                    $descriptions[$attribute->getVar('attribute_id')] = array(
997
                        'attribute_title'   => $attribute->getVar('attribute_title'),
998
                        'attribute_options' => $dataForDescriptions
999
                    );
1000
                }
1001
            }
1002
        }
1003
1004
        return $ret;
1005
    }
1006
}
1007