Completed
Pull Request — master (#126)
by
unknown
01:36
created

CartCondition::valueIsToBeAdded()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php namespace Darryldecode\Cart;
2
use Darryldecode\Cart\Exceptions\InvalidConditionException;
3
use Darryldecode\Cart\Helpers\Helpers;
4
use Darryldecode\Cart\Validators\CartConditionValidator;
5
6
/**
7
 * Created by PhpStorm.
8
 * User: darryl
9
 * Date: 1/15/2015
10
 * Time: 9:02 PM
11
 */
12
13
class CartCondition {
14
15
    /**
16
     * @var array
17
     */
18
    private $args;
19
20
    /**
21
     * the parsed raw value of the condition
22
     *
23
     * @var
24
     */
25
    private $parsedRawValue;
26
27
    private $config;
28
29
    /**
30
     * @param array $args (name, type, target, value)
31
     * @throws InvalidConditionException
32
     */
33
    public function __construct(array $args)
34
    {
35
        $this->args = $args;
36
37
        if( Helpers::isMultiArray($args) )
38
        {
39
            Throw new InvalidConditionException('Multi dimensional array is not supported.');
40
        }
41
        else
42
        {
43
            $this->validate($this->args);
44
        }
45
46
        $this->config = config('shopping_cart');
47
    }
48
49
    /**
50
     * the target of where the condition is applied
51
     *
52
     * @return mixed
53
     */
54
    public function getTarget()
55
    {
56
        return $this->args['target'];
57
    }
58
59
    /**
60
     * the name of the condition
61
     *
62
     * @return mixed
63
     */
64
    public function getName()
65
    {
66
        return $this->args['name'];
67
    }
68
69
    /**
70
     * the type of the condition
71
     *
72
     * @return mixed
73
     */
74
    public function getType()
75
    {
76
        return $this->args['type'];
77
    }
78
79
    /**
80
     * get the additional attributes of a condition
81
     *
82
     * @return array
83
     */
84
    public function getAttributes()
85
    {
86
        return (isset($this->args['attributes'])) ? $this->args['attributes'] : array();
87
    }
88
89
    /**
90
     * the value of this the condition
91
     *
92
     * @return mixed
93
     */
94
    public function getValue()
95
    {
96
        return $this->args['value'];
97
    }
98
99
    /**
100
     * Set the order to apply this condition. If no argument order is applied we return 0 as
101
     * indicator that no assignment has been made
102
     * @param int $order
103
     * @return Integer
104
     */
105
    public function setOrder($order = 1)
106
    {
107
        $this->args['order'] = $order;
108
    }
109
110
    /**
111
     * the order to apply this condition. If no argument order is applied we return 0 as
112
     * indicator that no assignment has been made
113
     *
114
     * @return Integer
115
     */
116
    public function getOrder()
117
    {
118
        return isset($this->args['order']) && is_numeric($this->args['order']) ? (int)$this->args['order'] : 0;
119
    }
120
121
    /**
122
     * apply condition to total or subtotal
123
     *
124
     * @param $totalOrSubTotalOrPrice
125
     * @return float
126
     */
127
    public function applyCondition($totalOrSubTotalOrPrice)
128
    {
129
        return $this->apply($totalOrSubTotalOrPrice, $this->getValue());
130
    }
131
132
    /**
133
     * get the calculated value of this condition supplied by the subtotal|price
134
     *
135
     * @param $totalOrSubTotalOrPrice
136
     * @return mixed
137
     */
138
    public function getCalculatedValue($totalOrSubTotalOrPrice)
139
    {
140
        $this->apply($totalOrSubTotalOrPrice, $this->getValue());
141
142
        return $this->parsedRawValue;
143
    }
144
145
    /**
146
     * get the calculated value of this condition supplied by the subtotal|price
147
     *
148
     * @param $totalOrSubTotalOrPrice
149
     * @return mixed
150
     */
151
    public function getCalculatedValueFormatted($totalOrSubTotalOrPrice)
152
    {
153
        $value = $this->getCalculatedValue($totalOrSubTotalOrPrice);
154
        return Helpers::formatValue($value, $this->config['format_numbers'], $this->config);
155
    }
156
157
    /**
158
     * apply condition
159
     *
160
     * @param $totalOrSubTotalOrPrice
161
     * @param $conditionValue
162
     * @return float
163
     */
164
    protected function apply($totalOrSubTotalOrPrice, $conditionValue)
165
    {
166
        $totalOrSubTotalOrPrice = Helpers::normalizePrice( $totalOrSubTotalOrPrice, $this->getConfig() );
167
        // if value has a percentage sign on it, we will get first
168
        // its percentage then we will evaluate again if the value
169
        // has a minus or plus sign so we can decide what to do with the
170
        // percentage, whether to add or subtract it to the total/subtotal/price
171
        // if we can't find any plus/minus sign, we will assume it as plus sign
172
        if( $this->valueIsPercentage($conditionValue) )
173
        {
174
            if( $this->valueIsToBeSubtracted($conditionValue) )
175
            {
176
                $value = Helpers::normalizePrice( $this->cleanValue($conditionValue), $this->getConfig() );
177
178
                $this->parsedRawValue = $totalOrSubTotalOrPrice * ($value / 100);
179
180
                $result = floatval($totalOrSubTotalOrPrice - $this->parsedRawValue);
181
            }
182
            else if ( $this->valueIsToBeAdded($conditionValue) )
183
            {
184
                $value = Helpers::normalizePrice( $this->cleanValue($conditionValue), $this->getConfig() );
185
186
                $this->parsedRawValue = $totalOrSubTotalOrPrice * ($value / 100);
187
188
                $result = floatval($totalOrSubTotalOrPrice + $this->parsedRawValue);
189
            }
190
            else
191
            {
192
                $value = Helpers::normalizePrice($conditionValue, $this->getConfig());
193
                
194
                $this->parsedRawValue = $totalOrSubTotalOrPrice * ($value / 100);
195
196
                $result = floatval($totalOrSubTotalOrPrice + $this->parsedRawValue);
197
            }
198
        }
199
200
        // if the value has no percent sign on it, the operation will not be a percentage
201
        // next is we will check if it has a minus/plus sign so then we can just deduct it to total/subtotal/price
202
        else
203
        {
204
            if( $this->valueIsToBeSubtracted($conditionValue) )
205
            {
206
                $this->parsedRawValue = Helpers::normalizePrice( $this->cleanValue($conditionValue), $this->getConfig() );
207
208
                $result = floatval($totalOrSubTotalOrPrice - $this->parsedRawValue);
209
            }
210
            else if ( $this->valueIsToBeAdded($conditionValue) )
211
            {
212
                $this->parsedRawValue = Helpers::normalizePrice( $this->cleanValue($conditionValue), $this->getConfig() );
213
214
                $result = floatval($totalOrSubTotalOrPrice + $this->parsedRawValue);
215
            }
216
            else
217
            {
218
                $this->parsedRawValue = Helpers::normalizePrice($conditionValue, $this->getConfig());
219
220
                $result = floatval($totalOrSubTotalOrPrice + $this->parsedRawValue);
221
            }
222
        }
223
224
        // Do not allow items with negative prices.
225
        return $result < 0 ? 0.00 : $result;
226
    }
227
228
    /**
229
     * check if value is a percentage
230
     *
231
     * @param $value
232
     * @return bool
233
     */
234
    protected function valueIsPercentage($value)
235
    { 
236
        return (preg_match('/%/', $value) == 1);
237
    }
238
239
    /**
240
     * check if value is a subtract
241
     *
242
     * @param $value
243
     * @return bool
244
     */
245
    protected function valueIsToBeSubtracted($value)
246
    {
247
        return (preg_match('/\-/', $value) == 1);
248
    }
249
250
    /**
251
     * check if value is to be added
252
     *
253
     * @param $value
254
     * @return bool
255
     */
256
    protected function valueIsToBeAdded($value)
257
    {
258
        return (preg_match('/\+/', $value) == 1);
259
    }
260
261
    /**
262
     * removes some arithmetic signs (%,+,-) only
263
     *
264
     * @param $value
265
     * @return mixed
266
     */
267
    protected function cleanValue($value)
268
    {
269
        return str_replace(array('%','-','+'),'',$value);
270
    }
271
272
    /**
273
     * validates condition arguments
274
     *
275
     * @param $args
276
     * @throws InvalidConditionException
277
     */
278 View Code Duplication
    protected function validate($args)
279
    {
280
        $rules = array(
281
            'name' => 'required',
282
            'type' => 'required',
283
            'target' => 'required',
284
            'value' => 'required',
285
        );
286
287
        $validator = CartConditionValidator::make($args, $rules);
288
289
        if( $validator->fails() )
290
        {
291
            throw new InvalidConditionException($validator->messages()->first());
292
        }
293
    }
294
295
    protected function getConfig()
296
    {
297
        if ($this->config == null) {
298
            $this->config = config('shopping_cart');
299
        }
300
301
        return $this->config;
302
    }
303
}
304