AttributesHandler::getProductAttributesCount()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace XoopsModules\Oledrion;
4
5
/**
6
 * ****************************************************************************
7
 * oledrion - MODULE FOR XOOPS
8
 * Copyright (c) Hervé Thouzard (http://www.herve-thouzard.com/)
9
 *
10
 * You may not change or alter any portion of this comment or credits
11
 * of supporting developers from this source code or any supporting source code
12
 * which is considered copyrighted (c) material of the original comment or credit authors.
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
 *
17
 * @copyright       Hervé Thouzard (http://www.herve-thouzard.com/)
18
 * @license         http://www.fsf.org/copyleft/gpl.html GNU public license
19
 * @author          Hervé Thouzard (http://www.herve-thouzard.com/)
20
 *
21
 * Version :
22
 * ****************************************************************************
23
 */
24
25
use XoopsModules\Oledrion;
26
27
/**
28
 * Gestion des options (attributs) de produits
29
 *
30
 * @since 2.3.2009.03.10
31
 */
32
33
/*
34
// Les types d'option
35
define('OLEDRION_ATTRIBUTE_RADIO', 1);
36
define('OLEDRION_ATTRIBUTE_CHECKBOX', 2);
37
define('OLEDRION_ATTRIBUTE_SELECT', 3);
38
39
// Le séparateur de données utilisé en interne
40
define('OLEDRION_ATTRIBUTE_SEPARATOR', '|');
41
define('OLEDRION_EMPTY_OPTION', '');
42
43
// Le séparateur de ligne lorsque l'option est un bouton radio ou des cases à cocher
44
define('OLEDRION_ATTRIBUTE_CHECKBOX_WHITE_SPACE', 1);     // Séparateur de ligne = espace blanc
45
define('OLEDRION_ATTRIBUTE_CHECKBOX_NEW_LINE', 2);        // Séparateur de ligne = retour à la ligne
46
47
// Les options par défaut lorsque l'option est une liste déroulante
48
define('OLEDRION_ATTRIBUTE_SELECT_VISIBLE_OPTIONS', 1);    // Valeur par défaut, nombre d'options visibles
49
define('OLEDRION_ATTRIBUTE_SELECT_MULTIPLE', false);       // Valeur par défaut, sélecteur multiple ?
50
*/
51
52
/**
53
 * Class OledrionOledrion_attributesHandler
54
 */
55
class AttributesHandler extends OledrionPersistableObjectHandler
56
{
57
    /**
58
     * OledrionOledrion_attributesHandler constructor.
59
     * @param null|\XoopsDatabase $db
60
     */
61
    public function __construct(\XoopsDatabase $db = null)
62
    {
63
        //                             Table               Classe                  Id
64
        parent::__construct($db, 'oledrion_attributes', Attributes::class, 'attribute_id');
0 ignored issues
show
Bug introduced by
It seems like $db can also be of type null; however, parameter $db of XoopsModules\Oledrion\Ol...tHandler::__construct() does only seem to accept XoopsDatabase, maybe add an additional type check? ( Ignorable by Annotation )

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

64
        parent::__construct(/** @scrutinizer ignore-type */ $db, 'oledrion_attributes', Attributes::class, 'attribute_id');
Loading history...
65
    }
66
67
    /**
68
     * Supprime tous les attributs d'un produit
69
     *
70
     * @param int $attribute_product_id
71
     * @return bool Le résultat de la suppression
72
     * @since 2.3.2009.03.16
73
     */
74
    public function deleteProductAttributes($attribute_product_id)
75
    {
76
        $attribute_product_id = (int)$attribute_product_id;
77
78
        return $this->deleteAll(new \Criteria('attribute_product_id', $attribute_product_id, '='));
79
    }
80
81
    /**
82
     * Retourne le nombre total d'attributs d'un produit (qu'ils soient obligatoires ou pas)
83
     *
84
     * @param int $attribute_product_id
85
     * @return int
86
     * @since 2.3.2009.03.16
87
     */
88
    public function getProductAttributesCount($attribute_product_id)
89
    {
90
        return $this->getCount(new \Criteria('attribute_product_id', $attribute_product_id, '='));
91
    }
92
93
    /**
94
     * Retourne la liste des attributs d'un produit
95
     *
96
     * @param  int|array  $product_id Le produit concerné
97
     * @param  null|array $attributesIds
98
     * @return array
99
     */
100
    public function getProductsAttributesList($product_id, $attributesIds = null)
101
    {
102
        $ret      = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $ret is dead and can be removed.
Loading history...
103
        $criteria = new \CriteriaCompo();
104
        if (is_array($product_id)) {
105
            $criteria->add(new \Criteria('attribute_product_id', '(' . implode(',', $product_id) . ')', 'IN'));
106
        } else {
107
            $criteria->add(new \Criteria('attribute_product_id', $product_id, '='));
108
        }
109
        if ($attributesIds && is_array($attributesIds)) {
110
            $criteria->add(new \Criteria('attribute_id', '(' . implode(',', array_keys($attributesIds)) . ')', 'IN'));
111
        }
112
        $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é
113
        $ret = $this->getObjects($criteria);
114
115
        return $ret;
116
    }
117
118
    /**
119
     * Construction de la liste des attributs d'un produit
120
     *
121
     * @param  Products $product              Le produit concerné
122
     * @param int       $mandatoryFieldsCount Retourne le nombre d'options requises
123
     * @return array                    Les options construites en html
124
     * @since 2.3.2009.03.16
125
     */
126
    public function constructHtmlProductAttributes(Products $product, &$mandatoryFieldsCount = 0)
127
    {
128
        $ret        = [];
129
        $attributes = $this->getProductsAttributesList($product->getVar('product_id'));
0 ignored issues
show
Bug introduced by
It seems like $product->getVar('product_id') can also be of type boolean and string; however, parameter $product_id of XoopsModules\Oledrion\At...roductsAttributesList() does only seem to accept array|integer, maybe add an additional type check? ( Ignorable by Annotation )

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

129
        $attributes = $this->getProductsAttributesList(/** @scrutinizer ignore-type */ $product->getVar('product_id'));
Loading history...
130
        if (0 === count($attributes)) {
131
            return $ret;
132
        }
133
        foreach ($attributes as $attribute) {
134
            if ((bool)$attribute->getVar('attribute_mandatory')) {
135
                ++$mandatoryFieldsCount;
136
            }
137
            $ret[] = $attribute->render($product);
138
        }
139
140
        return $ret;
141
    }
142
143
    /**
144
     * Retourne le montant initial des options d'un produit
145
     *
146
     * @param  Products $product
147
     * @return float
148
     */
149
    public function getInitialOptionsPrice(Products $product)
150
    {
151
        $ret        = 0;
152
        $attributes = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $attributes is dead and can be removed.
Loading history...
153
        $attributes = $this->getProductsAttributesList($product->getVar('product_id'));
0 ignored issues
show
Bug introduced by
It seems like $product->getVar('product_id') can also be of type boolean and string; however, parameter $product_id of XoopsModules\Oledrion\At...roductsAttributesList() does only seem to accept array|integer, maybe add an additional type check? ( Ignorable by Annotation )

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

153
        $attributes = $this->getProductsAttributesList(/** @scrutinizer ignore-type */ $product->getVar('product_id'));
Loading history...
154
        foreach ($attributes as $attribute) {
155
            $ret += $attribute->getDefaultAttributePrice();
156
        }
157
158
        return $ret;
159
    }
160
161
    /**
162
     * Clonage d'un attribut
163
     *
164
     * @param  Attributes $originalAttribute
165
     * @return mixed               Soit le nouvel attribut si tout a bien marché sinon false
166
     * @internal param Oledrion_attributes $attribute L'attribute à cloner
167
     * @since    2.3.2009.03.16
168
     */
169
    public function cloneAttribute(Attributes $originalAttribute)
170
    {
171
        $newAttribute = $originalAttribute->xoopsClone();
172
        if (OLEDRION_DUPLICATED_PLACE === 'right') {
0 ignored issues
show
introduced by
The condition XoopsModules\Oledrion\OL...CATED_PLACE === 'right' is always true.
Loading history...
173
            $newAttribute->setVar('attribute_title', $originalAttribute->getVar('attribute_title') . ' ' . _AM_OLEDRION_DUPLICATED);
174
        } else {
175
            $newAttribute->setVar('attribute_title', _AM_OLEDRION_DUPLICATED . ' ' . $originalAttribute->getVar('attribute_title'));
176
        }
177
        $newAttribute->setVar('attribute_id', 0);
178
        $newAttribute->setNew();
179
180
        $res = $this->insert($newAttribute, true);
181
        if ($res) {
182
            return $newAttribute;
183
        }
184
185
        return false;
186
    }
187
188
    /**
189
     * Retourne la liste des produits utilisés dans la table (liste unique)
190
     *
191
     * @return array Value = id produits (uniques)
192
     * @since 2.3.2009.03.16
193
     */
194
    public function getDistinctsProductsIds()
195
    {
196
        $ret = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $ret is dead and can be removed.
Loading history...
197
        $ret = $this->getDistincts('attribute_product_id');
198
        if (count($ret) > 0) {
199
            return array_values($ret);
200
        }
201
202
        return $ret;
203
    }
204
205
    /**
206
     * Suppression d'un attribut (et de ce qui y est rattaché)
207
     *
208
     * @param  Attributes $attribute
209
     * @return bool
210
     * @since 2.3.2009.03.17
211
     */
212
    public function deleteAttribute(Attributes $attribute)
213
    {
214
        return $this->delete($attribute, true);
215
        // TODO: Delete attributes in basket
216
    }
217
218
    /**
219
     * Retourne le nombre d'attributs obligatoires d'un produit
220
     *
221
     * @param  Products $product
222
     * @return int
223
     * @since 2.3.2009.03.20
224
     */
225
    public function getProductMandatoryAttributesCount(Products $product)
226
    {
227
        $criteria = new \CriteriaCompo();
228
        $criteria->add(new \Criteria('attribute_product_id', $product->getVar('attribute_product_id'), '='));
0 ignored issues
show
Bug introduced by
It seems like $product->getVar('attribute_product_id') can also be of type array and array; however, parameter $value of Criteria::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

228
        $criteria->add(new \Criteria('attribute_product_id', /** @scrutinizer ignore-type */ $product->getVar('attribute_product_id'), '='));
Loading history...
229
        $criteria->add(new \Criteria('attribute_mandatory', 1, '='));
230
231
        return $this->getCount($criteria);
232
    }
233
234
    /**
235
     * Retourne le nom des champs (représentant les attributs) obligatoires que l'on devrait trouver suite à une sélection de produit
236
     *
237
     * @param  Products $product
238
     * @return array             objets des type Oledrion_attributes
239
     */
240
    public function getProductMandatoryFieldsList(Products $product)
241
    {
242
        $criteria = new \CriteriaCompo();
243
        $criteria->add(new \Criteria('attribute_product_id', $product->getVar('attribute_product_id'), '='));
0 ignored issues
show
Bug introduced by
It seems like $product->getVar('attribute_product_id') can also be of type array and array; however, parameter $value of Criteria::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

243
        $criteria->add(new \Criteria('attribute_product_id', /** @scrutinizer ignore-type */ $product->getVar('attribute_product_id'), '='));
Loading history...
244
        $criteria->add(new \Criteria('attribute_mandatory', 1, '='));
245
246
        return $this->getObjects($criteria);
247
    }
248
249
    /**
250
     * Calcul le prix HT des options sélectionnées pour un produit
251
     *
252
     * @param  array $choosenAttributes [clé] = attribute_id, [value] = array(valueId1, valueId2 ...)
253
     * @param int    $product_vat_id    L'ID de TVA du produit
254
     * @param  array $descriptions      Tableau valorisé par la méthode [clé] = Id attribut [valeur] = array('attribute_title', array('attribute_names', 'attribute_prices'))
255
     * @return float
256
     * @since 2.3.2009.03.21
257
     */
258
    public function getProductOptionsPrice($choosenAttributes, $product_vat_id, &$descriptions = null)
259
    {
260
        $db         = \XoopsDatabaseFactory::getDatabaseConnection();
261
        $vatHandler = new Oledrion\VatHandler($db);
262
        $vat_rate   = 0;
263
        static $vats = [];
264
        if (is_array($vats) && isset($vats[$product_vat_id])) {
265
            $vat_rate = $vats[$product_vat_id];
266
        } else {
267
            $vat = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $vat is dead and can be removed.
Loading history...
268
            $vat = $vatHandler->get($product_vat_id);
269
            if (is_object($vat)) {
270
                $vats[$product_vat_id] = $vat_rate = $vat->getVar('vat_rate', 'n');
271
            }
272
        }
273
        $ret           = 0;
274
        $attributesIds = $attributes = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $attributesIds is dead and can be removed.
Loading history...
Unused Code introduced by
The assignment to $attributes is dead and can be removed.
Loading history...
275
        if (!is_array($choosenAttributes) || 0 === count($choosenAttributes)) {
0 ignored issues
show
introduced by
The condition is_array($choosenAttributes) is always true.
Loading history...
276
            return $ret;
277
        }
278
        $attributesIds = array_keys($choosenAttributes);
279
280
        $attributes = $this->getItemsFromIds($attributesIds);
281
        if (0 === count($attributes)) {
282
            return $ret;
283
        }
284
        $oledrionCurrency = Oledrion\Currency::getInstance();
285
286
        foreach ($choosenAttributes as $userAttributeId => $userAttributeValues) {
287
            if (isset($attributes[$userAttributeId])) {
288
                /** @var \XoopsModules\Oledrion\Attributes $attribute */
289
                $attribute           = $attributes[$userAttributeId];
290
                $dataForDescriptions = [];
291
                $optionDescription   = '';
292
                if ($userAttributeValues && is_array($userAttributeValues)) {
293
                    foreach ($userAttributeValues as $option) {
294
                        $optionName            = Oledrion\Utility::getName($option);
295
                        $price                 = $attribute->getOptionPriceFromValue($optionName);
296
                        $optionDescription     = $attribute->getOptionNameFromValue($optionName);
297
                        $vatAmount             = Oledrion\Utility::getVAT($price, $vat_rate);
298
                        $ttc                   = $price + $vatAmount;
299
                        $vatAmountFormated     = $oledrionCurrency->amountForDisplay($vatAmount);
300
                        $htFormated            = $oledrionCurrency->amountForDisplay($price);
301
                        $ttcFormated           = $oledrionCurrency->amountForDisplay($ttc);
302
                        $dataForDescriptions[] = [
303
                            'option_name'              => $optionDescription,
304
                            'option_value'             => $optionName,
305
                            'option_price'             => $price,
306
                            'option_vat'               => $vatAmount,
307
                            'option_ttc'               => $ttc,
308
                            'option_price_ht_formated' => $htFormated,
309
                            'option_vat_formated'      => $vatAmountFormated,
310
                            'option_ttc_formated'      => $ttcFormated,
311
                        ];
312
                        $ret                   += $price;    // Total de toutes les options
313
                    }
314
                } else {
315
                    $optionName            = Oledrion\Utility::getName($userAttributeValues);
316
                    $price                 = $attribute->getOptionPriceFromValue($optionName);
317
                    $optionDescription     = $attribute->getOptionNameFromValue($optionName);
318
                    $vatAmount             = Oledrion\Utility::getVAT($price, $vat_rate);
319
                    $ttc                   = $price + $vatAmount;
320
                    $vatAmountFormated     = $oledrionCurrency->amountForDisplay($vatAmount);
321
                    $htFormated            = $oledrionCurrency->amountForDisplay($price);
322
                    $ttcFormated           = $oledrionCurrency->amountForDisplay($ttc);
323
                    $dataForDescriptions[] = [
324
                        'option_name'              => $optionDescription,
325
                        'option_value'             => $optionName,
326
                        'option_price'             => $price,
327
                        'option_vat'               => $vatAmount,
328
                        'option_ttc'               => $ttc,
329
                        'option_price_ht_formated' => $htFormated,
330
                        'option_vat_formated'      => $vatAmountFormated,
331
                        'option_ttc_formated'      => $ttcFormated,
332
                    ];
333
                    $ret                   += $price;    // Total de toutes les options
334
                }
335
                if (is_array($descriptions)) {
336
                    $descriptions[$attribute->getVar('attribute_id')] = [
337
                        'attribute_title'   => $attribute->getVar('attribute_title'),
338
                        'attribute_options' => $dataForDescriptions,
339
                    ];
340
                }
341
            }
342
        }
343
344
        return $ret;
345
    }
346
}
347