ZonedShippingRate   A
last analyzed

Complexity

Total Complexity 1

Size/Duplication

Total Lines 43
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Importance

Changes 0
Metric Value
wmc 1
lcom 0
cbo 2
dl 0
loc 43
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A getCMSFields() 0 7 1
1
<?php
2
/**
3
 * Zoned shipping is a variant of TableShipping that regionalises using zones,
4
 * which are collections of regions, rather than regionalising using specific
5
 * locations / wildcards.
6
 *
7
 * @package silvershop-shipping
8
 */
9
class ZonedShippingMethod extends ShippingMethod
10
{
11
    private static $defaults = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
12
        'Name' => 'Zoned Shipping',
13
        'Description' => 'Works out shipping from a pre-defined zone rates'
14
    );
15
16
    private static $has_many = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
17
        "Rates" => "ZonedShippingRate"
18
    );
19
20
    public function calculateRate(ShippingPackage $package, Address $address)
21
    {
22
        $rate = null;
23
        $ids = Zone::get_zones_for_address($address);
24
        if (!$ids->exists()) {
25
            return $rate;
26
        }
27
        $ids = $ids->map('ID', 'ID')->toArray();
28
        $packageconstraints = array(
29
            "Weight" => 'weight',
30
            "Volume" => 'volume',
31
            "Value" => 'value',
32
            "Quantity" => 'quantity'
33
        );
34
        $constraintfilters = array();
35
        $emptyconstraint = array();
36
        foreach ($packageconstraints as $db => $pakval) {
37
            $mincol = "\"ZonedShippingRate\".\"{$db}Min\"";
38
            $maxcol = "\"ZonedShippingRate\".\"{$db}Max\"";
39
            $constraintfilters[] = "(".
40
                "$mincol >= 0" .
41
                " AND $mincol <= " . $package->{$pakval}() .
42
                " AND $maxcol > 0". //ignore constraints with maxvalue = 0
43
                " AND $maxcol >= " . $package->{$pakval}() .
44
                " AND $mincol < $maxcol" . //sanity check
45
            ")";
46
            //also include a special case where all constraints are empty
47
            $emptyconstraint[] = "($mincol = 0 AND $maxcol = 0)";
48
        }
49
        $constraintfilters[] = "(".implode(" AND ", $emptyconstraint).")";
50
51
        $filter = "(".implode(") AND (", array(
52
            "\"ZonedShippingMethodID\" = ".$this->ID,
53
            "\"ZoneID\" IN(".implode(",", $ids).")", //zone restriction
54
            implode(" OR ", $constraintfilters) //metrics restriction
55
        )).")";
56
        //order by zone specificity
57
        $orderby = "";
58
        if (count($ids) > 1) {
59
            $orderby = "CASE \"ZonedShippingRate\".\"ZoneID\"";
60
            $count = 1;
61
            foreach ($ids as $id) {
62
                $orderby .= " WHEN $id THEN $count ";
63
                $count ++;
64
            }
65
            $orderby .= "ELSE $count END ASC,";
66
        }
67
        $orderby .= "\"ZonedShippingRate\".\"Rate\" ASC";
68
        if ($sr = DataObject::get_one("ZonedShippingRate", $filter, true, $orderby)) {
69
            $rate = $sr->Rate;
70
        }
71
        $this->CalculatedRate = $rate;
0 ignored issues
show
Documentation introduced by
The property CalculatedRate does not exist on object<ZonedShippingMethod>. 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...
72
        return $rate;
73
    }
74
75
    public function getCMSFields()
76
    {
77
        $fields = parent::getCMSFields();
78
79
        $displayFieldsList = array(
80
            "ZoneID" =>  "Zone",
81
            "WeightMin" => "WeightMin",
82
            "WeightMax" => "WeightMax",
83
            "VolumeMin" => "VolumeMin",
84
            "VolumeMax" => "VolumeMax",
85
            "ValueMin" => "ValueMin",
86
            "ValueMax" => "ValueMax",
87
            "QuantityMin" => "QuantityMin",
88
            "QuantityMax" => "QuantityMax",
89
            "Rate" => "Rate"
90
        );
91
92
        $fields->fieldByName('Root')->removeByName("Rates");
93
        if ($this->isInDB()) {
94
            $gridField = new GridField("Rates", "ZonedShippingRate", $this->Rates(), new GridFieldConfig_RelationEditor());
0 ignored issues
show
Documentation Bug introduced by
The method Rates does not exist on object<ZonedShippingMethod>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
95
            $gridField->getConfig()->getComponentByType('GridFieldDataColumns')->setDisplayFields($displayFieldsList);
96
            $fields->addFieldToTab("Root.Main", $gridField);
97
        }
98
        return $fields;
99
    }
100
101
    /**
102
     * @return bool
103
     */
104
    public function requiresAddress()
105
    {
106
        return true;
107
    }
108
}
109
110
class ZonedShippingRate extends DataObject
111
{
112
    private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
113
        "WeightMin" => "Decimal",
114
        "WeightMax" => "Decimal",
115
        "VolumeMin" => "Decimal",
116
        "VolumeMax" => "Decimal",
117
        "ValueMin" => "Currency",
118
        "ValueMax" => "Currency",
119
        "QuantityMin" => "Int",
120
        "QuantityMax" => "Int",
121
122
        "Rate" => "Currency"
123
    );
124
125
    private static $has_one = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
126
        'Zone' => 'Zone',
127
        'ZonedShippingMethod' => 'ZonedShippingMethod'
128
    );
129
130
    private static $summary_fields = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
131
        'Zone.Name' => 'Zone',
132
        'WeightMin',
133
        'WeightMax',
134
        'VolumeMin',
135
        'VolumeMax',
136
        'ValueMin',
137
        'ValueMax',
138
        'QuantityMin',
139
        'QuantityMax',
140
        'Rate'
141
    );
142
143
    private static $default_sort = "\"Rate\" ASC";
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
144
145
    public function getCMSFields()
146
    {
147
        $fields = parent::getCMSFields();
148
        $fields->removeByName('ZonedShippingMethodID');
149
150
        return $fields;
151
    }
152
}
153