Completed
Push — master ( 8fbc16...5e2464 )
by darryl
11s
created

CartCondition::setOrder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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