1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
abstract class AddressCheckoutComponent extends CheckoutComponent |
4
|
|
|
{ |
5
|
|
|
/** @var string - Shipping or Billing */ |
6
|
|
|
protected $addresstype; |
7
|
|
|
|
8
|
|
|
/** @var bool */ |
9
|
|
|
private static $form_field_descriptions = true; |
10
|
|
|
|
11
|
2 |
|
/** @var bool */ |
12
|
|
|
protected $formfielddescriptions = true; |
13
|
2 |
|
|
14
|
|
|
/** @var bool - allows this to be overridden by config */ |
15
|
2 |
|
private static $add_to_addressbook = true; |
16
|
|
|
|
17
|
2 |
|
/** @var bool - allows this to be overridden at runtime */ |
18
|
|
|
protected $addtoaddressbook; |
19
|
|
|
|
20
|
4 |
|
public function getFormFields(Order $order) |
21
|
|
|
{ |
22
|
4 |
|
return $this->getAddress($order)->getFrontEndFields( |
23
|
|
|
array( |
24
|
|
|
'addfielddescriptions' => $this->useFormFieldDescriptions(), |
25
|
2 |
|
) |
26
|
|
|
); |
27
|
2 |
|
} |
28
|
|
|
|
29
|
2 |
|
public function getRequiredFields(Order $order) |
30
|
|
|
{ |
31
|
2 |
|
return $this->getAddress($order)->getRequiredFields(); |
32
|
|
|
} |
33
|
|
|
|
34
|
2 |
|
public function validateData(Order $order, array $data) |
35
|
2 |
|
{ |
36
|
2 |
|
} |
37
|
|
|
|
38
|
2 |
|
public function getData(Order $order) |
39
|
|
|
{ |
40
|
2 |
|
$data = $this->getAddress($order)->toMap(); |
41
|
|
|
|
42
|
|
|
//merge data from multiple sources |
43
|
2 |
|
$data = array_merge( |
44
|
2 |
|
ShopUserInfo::singleton()->getLocation(), |
45
|
|
|
$data, |
46
|
|
|
array( |
47
|
|
|
$this->addresstype . "AddressID" => $order->{$this->addresstype . "AddressID"}, |
48
|
|
|
) |
49
|
|
|
); |
50
|
|
|
|
51
|
|
|
//merge in default address if an address isn't available |
52
|
|
|
$member = Member::currentUser(); |
53
|
|
|
if(!$order->{$this->addresstype . "AddressID"}) { |
54
|
2 |
|
$data = array_merge( |
55
|
2 |
|
ShopUserInfo::singleton()->getLocation(), |
56
|
2 |
|
$member ? $member->{"Default" . $this->addresstype . "Address"}()->toMap() : array(), |
57
|
|
|
array( |
58
|
|
|
$this->addresstype . "AddressID" => $order->{$this->addresstype . "AddressID"}, |
59
|
2 |
|
) |
60
|
2 |
|
); |
61
|
2 |
|
} |
62
|
|
|
|
63
|
2 |
|
unset($data['ID']); |
64
|
|
|
unset($data['ClassName']); |
65
|
|
|
unset($data['RecordClassName']); |
66
|
|
|
|
67
|
|
|
//ensure country is restricted if there is only one allowed country |
68
|
|
|
if ($country = SiteConfig::current_site_config()->getSingleCountry()) { |
69
|
|
|
$data['Country'] = $country; |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
return $data; |
73
|
2 |
|
} |
74
|
|
|
|
75
|
2 |
|
/** |
76
|
|
|
* Create a new address if the existing address has changed, or is not yet |
77
|
|
|
* created. |
78
|
2 |
|
* |
79
|
2 |
|
* @param Order $order order to get addresses from |
80
|
2 |
|
* @param array $data data to set |
81
|
2 |
|
* |
82
|
2 |
|
* @return Order |
83
|
2 |
|
*/ |
84
|
2 |
|
public function setData(Order $order, array $data) |
|
|
|
|
85
|
|
|
{ |
86
|
2 |
|
$address = $this->getAddress($order); |
87
|
2 |
|
//if the value matches the current address then unset |
88
|
2 |
|
//this is to fix issues with blank fields & the readonly Country field |
89
|
|
|
$addressfields = Address::database_fields(get_class($address)); |
90
|
2 |
|
foreach($data as $key => $value) { |
91
|
2 |
|
if(!isset($addressfields[$key]) || (!$value && !$address->{$key})) { |
92
|
2 |
|
unset($data[$key]); |
93
|
1 |
|
} |
94
|
1 |
|
} |
95
|
|
|
$address->update($data); |
96
|
2 |
|
//if only one country is available, then set it |
97
|
2 |
|
if ($country = SiteConfig::current_site_config()->getSingleCountry()) { |
98
|
1 |
|
$address->Country = $country; |
|
|
|
|
99
|
1 |
|
} |
100
|
2 |
|
//write new address, or duplicate if changed |
101
|
|
|
if (!$address->isInDB()) { |
102
|
2 |
|
$address->write(); |
103
|
2 |
|
} elseif ($address->isChanged()) { |
104
|
2 |
|
$address = $address->duplicate(); |
105
|
2 |
|
} |
106
|
|
|
//set billing address, if not already set |
107
|
2 |
|
$order->{$this->addresstype . "AddressID"} = $address->ID; |
108
|
2 |
|
if (!$order->BillingAddressID) { |
|
|
|
|
109
|
|
|
$order->BillingAddressID = $address->ID; |
|
|
|
|
110
|
2 |
|
} |
111
|
2 |
|
$order->write(); |
112
|
2 |
|
//update user info based on shipping address |
113
|
2 |
|
if ($this->addresstype === "Shipping") { |
114
|
2 |
|
ShopUserInfo::singleton()->setAddress($address); |
|
|
|
|
115
|
|
|
Zone::cache_zone_ids($address); |
|
|
|
|
116
|
|
|
} |
117
|
2 |
|
//associate member to address |
118
|
|
|
if ($member = Member::currentUser()) { |
119
|
2 |
|
$default = $member->{"Default" . $this->addresstype . "Address"}(); |
120
|
2 |
|
//set default address |
121
|
|
|
if (!$default->exists()) { |
122
|
|
|
$member->{"Default" . $this->addresstype . "AddressID"} = $address->ID; |
123
|
|
|
$member->write(); |
124
|
|
|
} |
125
|
|
|
if ($this->getAddToAddressBook()) { |
126
|
|
|
$member->AddressBook()->add($address); |
127
|
|
|
} |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
//extension hooks |
131
|
|
|
$order->extend('onSet' . $this->addresstype . 'Address', $address); |
132
|
|
|
|
133
|
4 |
|
return $order; |
134
|
|
|
} |
135
|
|
|
|
136
|
4 |
|
/** |
137
|
|
|
* Add new addresses to the address book. |
138
|
4 |
|
* |
139
|
|
|
* @param bool $add |
140
|
4 |
|
* |
141
|
|
|
* @return $this |
142
|
|
|
*/ |
143
|
|
|
public function setAddToAddressBook($add = true) |
144
|
|
|
{ |
145
|
|
|
$this->addtoaddressbook = $add; |
146
|
|
|
return $this; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* @return bool |
151
|
|
|
*/ |
152
|
|
|
public function getAddToAddressBook() |
153
|
1 |
|
{ |
154
|
|
|
if (isset($this->addtoaddressbook)) { |
155
|
|
|
return $this->addtoaddressbook; |
156
|
|
|
} else { |
157
|
|
|
return $this->config()->add_to_addressbook; |
158
|
|
|
} |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* @return boolean |
163
|
|
|
*/ |
164
|
|
|
public function useFormFieldDescriptions() |
165
|
|
|
{ |
166
|
|
|
if (isset($this->formfielddescriptions)) { |
167
|
|
|
return $this->formfielddescriptions; |
168
|
|
|
} else { |
169
|
|
|
return $this->config()->form_field_descriptions; |
170
|
|
|
} |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* @param boolean $formfielddescriptions |
175
|
|
|
* |
176
|
|
|
* @return $this |
177
|
|
|
*/ |
178
|
|
|
public function setFormFieldDescriptions($formfielddescriptions) |
179
|
|
|
{ |
180
|
|
|
$this->formfielddescriptions = $formfielddescriptions; |
181
|
|
|
return $this; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
|
185
|
|
|
/** |
186
|
|
|
* @param Order $order |
187
|
|
|
* |
188
|
|
|
* @return Address |
189
|
|
|
*/ |
190
|
|
|
public function getAddress(Order $order) |
191
|
|
|
{ |
192
|
|
|
return $order->{$this->addresstype . "Address"}(); |
193
|
|
|
} |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
class ShippingAddressCheckoutComponent extends AddressCheckoutComponent |
197
|
|
|
{ |
198
|
|
|
protected $addresstype = "Shipping"; |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
class BillingAddressCheckoutComponent extends AddressCheckoutComponent |
202
|
|
|
{ |
203
|
|
|
protected $addresstype = "Billing"; |
204
|
|
|
} |
205
|
|
|
|
A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.
You can also find more information in the “Code” section of your repository.