EcommerceCustomDeliveryModifier   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 260
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 33
lcom 1
cbo 3
dl 0
loc 260
rs 9.3999
c 0
b 0
f 0

18 Methods

Rating   Name   Duplication   Size   Complexity  
A getCMSFields() 0 5 1
A i18n_singular_name() 0 4 1
A i18n_plural_name() 0 4 1
A runUpdate() 0 7 1
A ShowForm() 0 4 1
A ShowFormInEditableOrderTable() 0 4 1
A ShowFormOutsideEditableOrderTable() 0 4 1
A ShowInTable() 0 4 2
A CanBeRemoved() 0 4 1
A LiveName() 0 16 4
A LiveCalculatedTotal() 0 12 2
A onBeforeWrite() 0 4 1
A LiveNonSpecialProductCount() 0 4 1
A LiveSpecialProductCount() 0 4 1
C ProductCountForTotal() 0 23 7
A LivePostalCode() 0 17 4
A SelectedProductsArray() 0 5 1
A MyPostalCodeObject() 0 12 2
1
<?php
2
3
/**
4
 * @author Nicolaas [at] sunnysideup.co.nz
5
 * @package: ecommerce
6
 * @sub-package: examples
7
 * @description: This is an example modifier that developers can use
8
 * as a starting point for writing their own modifiers.
9
 *
10
 **/
11
class EcommerceCustomDeliveryModifier extends OrderModifier
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
12
{
13
14
// ######################################## *** model defining static variables (e.g. $db, $has_one)
15
16
    /**
17
     * add extra fields as you need them.
18
     *
19
     **/
20
    public static $db = array(
21
        "PostalCode" => "Varchar(10)",
22
        "SpecialProductCount" => "Int",
23
        "NonSpecialProductCount" => "Int"
24
    );
25
26
27
// ######################################## *** cms variables + functions (e.g. getCMSFields, $searchableFields)
28
29
    /**
30
     * standard SS method
31
     */
32
    public function getCMSFields()
33
    {
34
        $fields = parent::getCMSFields();
35
        return $fields;
36
    }
37
38
    public static $singular_name = "Delivery Charge";
39
    public function i18n_singular_name()
40
    {
41
        return self::$singular_name;
42
    }
43
44
    public static $plural_name = "Delivery Charges";
45
    public function i18n_plural_name()
46
    {
47
        return self::$plural_name;
48
    }
49
50
// ######################################## *** other (non) static variables (e.g. protected static $special_name_for_something, protected $order)
51
52
53
// ######################################## *** CRUD functions (e.g. canEdit)
54
// ######################################## *** init and update functions
55
56
    /**
57
     * For all modifers with their own database fields, we need to include this...
58
     * It will update each of the fields.
59
     * Within this method, we need to create the methods
60
     * Live{functionName}
61
     * e.g LiveMyField() and LiveMyReduction() in this case...
62
     * The OrderModifier already updates the basic database fields.
63
     * @param Bool $force - run it, even if it has run already
64
     */
65
    public function runUpdate($force = false)
66
    {
67
        $this->checkField("PostalCode");
68
        $this->checkField("SpecialProductCount");
69
        $this->checkField("NonSpecialProductCount");
70
        parent::runUpdate($force);
71
    }
72
73
74
// ######################################## *** form functions (e. g. Showform and getform)
75
76
    /**
77
     * standard OrderModifier Method
78
     * Should we show a form in the checkout page for this modifier?
79
     */
80
    public function ShowForm()
81
    {
82
        return false;
83
    }
84
85
    /**
86
     * Should the form be included in the editable form
87
     * on the checkout page?
88
     * @return Boolean
89
     */
90
    public function ShowFormInEditableOrderTable()
91
    {
92
        return false;
93
    }
94
95
    /**
96
     * Should the form be included in the editable form
97
     * on the checkout page?
98
     * @return Boolean
99
     */
100
    public function ShowFormOutsideEditableOrderTable()
101
    {
102
        return false;
103
    }
104
105
// ######################################## *** template functions (e.g. ShowInTable, TableTitle, etc...) ... USES DB VALUES
106
107
    /**
108
     * standard OrderModifer Method
109
     * Tells us if the modifier should take up a row in the table on the checkout page.
110
     * @return Boolean
111
     */
112
    public function ShowInTable()
113
    {
114
        return $this->PostalCode ? true : false;
0 ignored issues
show
Documentation introduced by
The property PostalCode does not exist on object<EcommerceCustomDeliveryModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
115
    }
116
117
    /**
118
     * standard OrderModifer Method
119
     * Tells us if the modifier can be removed (hidden / turned off) from the order.
120
     * @return Boolean
121
     */
122
    public function CanBeRemoved()
123
    {
124
        return false;
125
    }
126
127
// ######################################## ***  inner calculations.... USES CALCULATED VALUES
128
129
130
131
// ######################################## *** calculate database fields: protected function Live[field name]  ... USES CALCULATED VALUES
132
133
    /**
134
     * if we want to change the default value for the Name field
135
     * (defined in the OrderModifer class) then we can do this
136
     * as shown in the method below.
137
     * You may choose to return an empty string or just a standard message.
138
     **/
139
    protected function LiveName()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
140
    {
141
        if ($obj = $this->MyPostalCodeObject()) {
142
            $title = $obj->Title;
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<EcommerceCustomDeliveryPostalCode>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
143
        } else {
144
            $title = EcommerceDBConfig::current_ecommerce_db_config()->DeliveryChargeTitle;
145
        }
146
        if ($postalCode = $this->LivePostalCode()) {
147
            if ($postalCodeLabel = _t("EcommerceCustomDeliveryModifier.POSTAL_CODE", "postal code")) {
148
                $title .= " (".$postalCodeLabel.": ".$postalCode.")";
149
            }
150
        } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
151
            //do nothing...
152
        }
153
        return $title;
154
    }
155
156
    protected function LiveCalculatedTotal()
157
    {
158
        $nonSpecialCount =  $this->LiveNonSpecialProductCount();
159
        $postalCodeObject =  $this->MyPostalCodeObject();
160
        if (!$postalCodeObject) {
161
            $postalCodeObject = EcommerceDBConfig::current_ecommerce_db_config();
162
        }
163
        $specialCount =  $this->LiveSpecialProductCount();
164
        return
165
            ($postalCodeObject->PriceWithoutApplicableProducts * $nonSpecialCount) +
166
            ($postalCodeObject->PriceWithApplicableProducts * $specialCount);
167
    }
168
169
170
171
// ######################################## *** Type Functions (IsChargeable, IsDeductable, IsNoChange, IsRemoved)
172
173
174
175
// ######################################## *** standard database related functions (e.g. onBeforeWrite, onAfterWrite, etc...)
176
177
    public function onBeforeWrite()
178
    {
179
        parent::onBeforeWrite();
180
    }
181
182
// ######################################## *** debug functions
183
184
    public function LiveNonSpecialProductCount()
185
    {
186
        return $this->ProductCountForTotal(false);
187
    }
188
189
    public function LiveSpecialProductCount()
190
    {
191
        return $this->ProductCountForTotal(true);
192
    }
193
194
    /**
195
     * @return int
196
     */
197
    protected function ProductCountForTotal($special = false)
198
    {
199
        $specialCount = 0;
200
        $nonSpecialCount = 0;
201
        $applicableProducts = $this->SelectedProductsArray();
202
        if (count($applicableProducts)) {
203
            $order = $this->Order();
204
            if ($order) {
205
                foreach ($order->OrderItems() as $item) {
206
                    if ($special && in_array($item->Product()->ID, $applicableProducts)) {
207
                        $specialCount += $item->Quantity;
208
                    } else {
209
                        $nonSpecialCount += $item->Quantity;
210
                    }
211
                }
212
            }
213
        }
214
        if ($special) {
215
            return $specialCount;
216
        } else {
217
            return $nonSpecialCount;
218
        }
219
    }
220
221
    /**
222
     *
223
     * @return String
224
     */
225
    public function LivePostalCode()
226
    {
227
        $postalCode = "";
228
        $order = $this->Order();
229
        if ($order) {
230
            $shippingAddress = $order->CreateOrReturnExistingAddress("ShippingAddress");
231
            $postalCode = $shippingAddress->ShippingPostalCode;
232
            if (!$postalCode) {
233
                $billingAddress = $order->CreateOrReturnExistingAddress("BillingAddress");
234
                $postalCode = $billingAddress->PostalCode;
235
            }
236
        }
237
        if (intval($postalCode) > 0) {
238
            return $postalCode;
239
        }
240
        return "";
241
    }
242
243
244
    /**
245
     *
246
     * @array
247
     */
248
    private function SelectedProductsArray()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
249
    {
250
        $ecommerceConfig = EcommerceDBConfig::current_ecommerce_db_config();
251
        return $ecommerceConfig->DeliverySpecialChargedProducts()->map("ID", "ID")->toArray();
252
    }
253
254
    /**
255
     *
256
     * @return EcommerceCustomDeliveryPostalCode | null
257
     */
258
    private function MyPostalCodeObject()
259
    {
260
        $ecommerceConfig = EcommerceDBConfig::current_ecommerce_db_config();
261
        $postalCode = intval($this->LivePostalCode());
262
        if ($postalCode) {
263
            return $ecommerceConfig->SpecialPricePostalCodes()
264
                ->where(
265
                    "$postalCode >= \"PostalCodeLowestNumber\" AND $postalCode <= \"PostalCodeHighestNumber\" "
266
                )->First();
267
        }
268
        return null;
269
    }
270
}
271