Completed
Push — master ( 9cb4e7...12538c )
by Lawrence
02:09
created

Combination::getProductName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 7
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 7
loc 7
rs 9.4285
cc 1
eloc 4
nc 1
nop 1
1
<?php
2
3
namespace ABM\Wasabi;
4
5
use Analog\Analog;
6
7
class Combination extends Prestashop
8
{
9
    /**
10
     * @param string $data
11
     */
12
    public function getCombinationData($data)
13
    {
14
        $product = substr($data, 0, strpos($data, ','));
15
        $combinations = [];
16
        $vars = explode(',', $data);
17
        Analog::log("Product variables: $data");
18
        $choices = array_slice($vars, 1);
19
        $id_product_attribute = $this->getAttribute($product, $choices);
20
        Analog::log("Product combination: $id_product_attribute");
21
        $combo_groups = $this->getCombination($product, $id_product_attribute);
22
        if (!empty($combo_groups) && is_array($combo_groups) && $combo_groups) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $combo_groups of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
23
            foreach ($combo_groups as $k => $row) {
24
                $combinations = $this->buildAttributes($combinations, $id_product_attribute, $row);
25
            }
26
        }
27
28
        return $combinations;
29
    }
30
31
    /**
32
     * @param string $product
33
     */
34
    private function getAttribute($product, $choices)
35
    {
36
        $sql = 'SELECT pac.id_product_attribute from '._DB_PREFIX_.'product_attribute_combination as pac
37
                LEFT JOIN  '._DB_PREFIX_.'product_attribute as ppa on ppa.id_product_attribute = pac.id_product_attribute
38
                LEFT JOIN '._DB_PREFIX_.'attribute a ON (a.id_attribute = pac.id_attribute)
39
                WHERE ppa.id_product = '.$product;
40
        foreach ($choices as $value) {
41
            $sql .= ' AND pac.id_product_attribute IN
42
                    ( SELECT pac.id_product_attribute from '._DB_PREFIX_.'product_attribute_combination as pac
43
                    WHERE pac.id_attribute = '.(int) $value.')  ';
44
        }
45
        $sql .= ' GROUP BY pac.id_product_attribute';
46
        $id_product_attribute = $this->dbConn->fetchColumn($sql);
47
48
        return $id_product_attribute;
49
    }
50
51
    /**
52
     * @param null|string $id_product_attribute
53
     */
54
    private function buildAttributes($combinations, $id_product_attribute, $row)
55
    {
56
        $combinationSet = [];
57
        $specific_price = null;
58
59
        $combinations['name'] = $row['product_name'];
60
        $typcheck = ['id_product', 'price', 'base_price', 'price', 'ecotax', 'weight', 'quantity', 'unit_impact', 'minimal_quantity'];
61
62
        foreach ($typcheck as $key => $value) {
63
            ((strpos($value, 'price') !== false) || (strpos($value, 'weight') !== false) || (strpos($value, 'ecotax') !== false) || (strpos($value, 'impact') !== false)) ? $combinations[$value] = (float) $row[$value] : $combinations[$value] = (int) $row[$value];
64
        }
65
        $combinations['attributes_values'][$row['id_attribute_group']] = $row['attribute_name'];
66
        $combinations['attributes'][] = (int) $row['id_attribute'];
67
68
        list($combinationSet[(int) $row['id_product_attribute']], $combinations['specific_price']) = $this->getCombinationSpecificPrice($combinationSet, $row, $id_product_attribute);
69
70
        $combinations['reference'] = $row['reference'];
71
        $combinations['available_date'] = $this->getAvailableDate($row);
72
        $combinations['image'] = $this->getComboImage($id_product_attribute);
73
        $combinations['final_price'] = $this->getFinalPrice($row, $specific_price);
74
75
        return $combinations;
76
    }
77
78
    private function getFinalPrice($row, $specific_price)
79
    {
80
        $specific_price['price'] != 0 ? $final_price = (((float) $row['base_price'] + (float) $row['price']) * (((int) 100 - $specific_price['reduction_percent']) / 100)) : $final_price = (float) $row['base_price'] + (float) $row['price'];
81
82
        return $final_price;
83
    }
84
85
    private function getAvailableDate($row)
86
    {
87
        ($row['available_date'] != '0000-00-00') ? $dater = $row['available_date'] : $dater = '';
88
89
        return $dater;
90
    }
91
92
    /**
93
     * @param null|string $id_product_attribute
94
     */
95
    private function getCombinationSpecificPrice($combinationSet, $row, $id_product_attribute)
96
    {
97
        // Call getSpecificPrice in order to set $combination_specific_price
98
                if (!isset($combinationSet[(int) $row['id_product_attribute']])) {
99
                    $specific_price = $this->getSpecificPrice($id_product_attribute, $row['id_product']);
100
                    $combinationSet[(int) $row['id_product_attribute']] = true;
101
102
                    return [$combinationSet, $specific_price];
103
                } else {
104
                    return [false, null];
105
                }
106
    }
107
108
    /**
109
     * @param null|string $id_product_attribute
110
     * @param string      $product
111
     */
112
    private function getCombination($product, $id_product_attribute)
113
    {
114
        $combo = $this->getAttributeBase($id_product_attribute);
115
116
        if (is_array($combo)) {
117
            foreach ($combo as $key => $value) {
118
                $combo['base_price'] = (float) Product::getOrderPrice($product);
0 ignored issues
show
Bug introduced by
The method getOrderPrice() cannot be called from this context as it is declared private in class ABM\Wasabi\Product.

This check looks for access to methods that are not accessible from the current context.

If you need to make a method accessible to another context you can raise its visibility level in the defining class.

Loading history...
119
                $combo['quantity'] = (int) $this->getStockQuantity($product, $id_product_attribute);
120
                $combo['id_product'] = (int) $product;
121
                $combo['product_name'] = (int) $this->getProductName($product);
122
                $pricing = $this->getAttributePricing($id_product_attribute);
123
                foreach ($pricing as $ki => $val) {
0 ignored issues
show
Bug introduced by
The expression $pricing of type null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
124
                    $combo[$ki] = $val;
125
                }
126
            }
127
        }
128
129
        return $combo;
130
    }
131
132
    /**
133
     * @param null|string $attribute
134
     */
135
    private function getAttributeBase($attribute)
136
    {
137
        $sql = 'SELECT ag.id_attribute_group, ag.is_color_group, agl.name AS group_name, agl.public_name AS public_group_name,
138
                    a.id_attribute, al.name AS attribute_name, a.color AS attribute_color, ag.group_type, pac.id_product_attribute
139
            FROM '._DB_PREFIX_.'product_attribute_combination pac
140
            LEFT JOIN '._DB_PREFIX_.'attribute a ON (a.id_attribute = pac.id_attribute)
141
            LEFT JOIN  '._DB_PREFIX_.'attribute_group ag ON (ag.id_attribute_group = a.id_attribute_group)
142
            LEFT JOIN '._DB_PREFIX_.'attribute_lang al ON (a.id_attribute = al.id_attribute)
143
            LEFT JOIN '._DB_PREFIX_.'attribute_group_lang agl ON (ag.id_attribute_group = agl.id_attribute_group)
144
            WHERE pac.id_product_attribute='.(int) $attribute;
145
        $result = $this->dbConn->fetchRowMany($sql);
146
147
        return $result;
148
    }
149
150
    /**
151
     * @param null|string $attribute
152
     * @param string      $product
153
     */
154
    private function getStockQuantity($product, $attribute)
155
    {
156
        $sql = 'SELECT stock.quantity from '._DB_PREFIX_.'stock_available as stock WHERE stock.id_product = '.(int) $product.'AND stock.id_product_attribute = '.(int) $attribute;
157
        $result = $this->dbConn->fetchColumn($sql);
158
159
        return $result;
160
    }
161
162
    /**
163
     * @param null|string $attribute
164
     */
165
    private function getAttributePricing($attribute)
166
    {
167
        $sql = 'SELECT pas.price, pas.ecotax, pas.weight, pas.default_on, pa.reference, pas.unit_price_impact, 
168
                pas.minimal_quantity, pas.available_date FROM '._DB_PREFIX_.'product_attribute_shop pas 
169
                WHERE pas.id_product_attribute = '.(int) $attribute;
170
        $result = $this->dbConn->fetchRowMany($sql);
171
172
        return $result;
173
    }
174
175
    /**
176
     * @param null|string $id_product_attribute
177
     * @param string      $id_product
178
     */
179
    private function getSpecificPrice($id_product_attribute, $id_product)
180
    {
181
        $specific_price = [];
182
        if ($this->getNumberSpecificPrice($id_product_attribute, $id_product) > 0) {
183
            $result = $this->getSpecificPriceData($id_product_attribute, $id_product, date('Y-m-d H:i:s'));
184
            $specific_price['price'] = $result['price'];
185
            $specific_price['id_product_attribute'] = $result['id_product_attribute'];
186
            $specific_price['reduction_percent'] = (int) 100 * $result['reduction'];
187
            $specific_price['reduction_price'] = 0;
188
            $specific_price['reduction_type'] = $result['reduction_type'];
189
190
            return $specific_price;
191
        }
192
    }
193
194
    /**
195
     * @param string      $now
196
     * @param null|string $id_product_attribute
197
     * @param string      $id_product
198
     */
199
    private function getSpecificPriceData($id_product_attribute, $id_product, $now)
200
    {
201
        $sql = 'SELECT * FROM '._DB_PREFIX_.'specific_price
202
                            WWHERE id_product = '.(int) $id_product.'
203
                            AND id_product_attribute IN (0, '.(int) $id_product_attribute.')
204
                            AND (
205
                                   (from = \'0000-00-00 00:00:00\' OR \''.$now.'\' >= from)
206
                            AND
207
                                     (to = \'0000-00-00 00:00:00\' OR \''.$now.'\' <= to)
208
                            ) ';
209
210
        $sql .= ' ORDER BY id_product_attribute DESC, from_quantity DESC, id_specific_price_rule ASC';
211
212
        $result = $this->dbConn->fetchRow($sql);
213
214
        return $result;
215
    }
216
217
    /**
218
     * @param null|string $id_product_attribute
219
     * @param string      $id_product
220
     */
221
    private function getNumberSpecificPrice($id_product_attribute, $id_product)
222
    {
223
        $sql = 'SELECT COUNT(*) FROM '._DB_PREFIX_.'specific_price WHERE id_product = '.(int) $id_product.' AND id_product_attribute = 0';
224
        $spec = $this->dbConn->fetchColumn($sql);
225
        if ($spec == 0) {
226
            $sql = 'SELECT COUNT(*) FROM '._DB_PREFIX_.'specific_price WHERE id_product_attribute = '.(int) $id_product_attribute;
227
            $spec = $this->dbConn->fetchColumn($sql);
228
        }
229
230
        return $spec;
231
    }
232
233
    /**
234
     * @param null|string $id_product_attribute
235
     */
236
    private function getComboImage($id_product_attribute)
237
    {
238
        $sql = 'SELECT pai.id_imageas image
239
                        FROM '._DB_PREFIX_.'product_attribute_image pai
240
                        LEFT JOIN '._DB_PREFIX_.'image_lang il ON (il.id_image = pai.id_image)
241
                        LEFT JOIN '._DB_PREFIX_.'image i ON (i.id_image = pai.id_image)
242
                        WHERE pai.id_product_attribute = '.(int) $id_product_attribute.' ORDER by i.position';
243
        $image = $this->dbConn->fetchColumn($sql);
244
        ($image !== false) ? $imager = (int) $image : $imager = -1;
245
246
        return $imager;
247
    }
248
249
    /**
250
     * @param string $product
251
     */
252 View Code Duplication
    private function getProductName($product)
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...
253
    {
254
        $sql = 'SELECT pl.name from '._DB_PREFIX_.'product_lang as pl WHERE pl.id_product = '.(int) $product;
255
        $result = $this->dbConn->fetchColumn($sql);
256
257
        return $result;
258
    }
259
260
}
261