Skip to content

Commit cc0c5b1

Browse files
Ensure custom address fields are available in templates (#118)
1 parent 07c6994 commit cc0c5b1

File tree

7 files changed

+203
-139
lines changed

7 files changed

+203
-139
lines changed

src/Data/Address.php

Lines changed: 100 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,68 +5,136 @@
55
use Illuminate\Contracts\Support\Arrayable;
66
use Illuminate\Support\Facades\File;
77
use Statamic\Dictionaries\Item;
8+
use Statamic\Facades\Blueprint;
89
use Statamic\Facades\Dictionary;
10+
use Statamic\Fields\Field;
11+
use Statamic\Support\Arr;
12+
use Statamic\Support\Traits\Hookable;
913
use Stringable;
1014

1115
class Address implements Arrayable, Stringable
1216
{
13-
public function __construct(
14-
public ?string $name = null,
15-
public ?string $line1 = null,
16-
public ?string $line2 = null,
17-
public ?string $city = null,
18-
public ?string $postcode = null,
19-
public ?string $country = null,
20-
public ?string $state = null,
21-
) {}
17+
use Hookable;
18+
19+
public function __construct(protected array $address = []) {}
20+
21+
public static function make(array $address)
22+
{
23+
return new static($address);
24+
}
2225

2326
public function country(): ?Item
2427
{
25-
if (! $this->country) {
28+
$country = Arr::get($this->address, 'country');
29+
30+
if (! $country) {
2631
return null;
2732
}
2833

29-
return Dictionary::find('countries')->get($this->country);
34+
return Dictionary::find('countries')->get($country);
3035
}
3136

3237
public function state(): ?array
3338
{
34-
if (! $this->state) {
39+
$state = Arr::get($this->address, 'state');
40+
$country = Arr::get($this->address, 'country');
41+
42+
if (! $country || ! $state) {
3543
return null;
3644
}
3745

3846
$states = File::json(__DIR__.'/../../resources/json/states.json');
3947

40-
if (! isset($states[$this->country])) {
48+
if (! isset($states[$country])) {
4149
return null;
4250
}
4351

44-
return array_values(array_filter($states[$this->country], fn ($state) => $state['code'] === $this->state))[0];
52+
return collect($states[$country])->firstWhere('code', $state);
4553
}
4654

4755
public function toArray(): array
4856
{
49-
return [
50-
'name' => $this->name,
51-
'line_1' => $this->line1,
52-
'line_2' => $this->line2,
53-
'city' => $this->city,
54-
'postcode' => $this->postcode,
55-
'country' => $this->country,
56-
'state' => $this->state,
57-
];
57+
return $this->address;
5858
}
5959

6060
public function __toString(): string
6161
{
62-
return collect([
63-
$this->name,
64-
$this->line1,
65-
$this->line2,
66-
$this->city,
67-
$this->state() ? $this->state()['name'] : null,
68-
$this->postcode,
69-
$this->country()?->extra()['name'],
70-
])->filter()->implode(', ');
62+
return static::blueprint()->fields()->all()
63+
->map(function (Field $field) {
64+
$value = Arr::get($this->address, $field->handle());
65+
66+
if ($field->handle() === 'state') {
67+
return $this->state()['name'] ?? null;
68+
}
69+
70+
if ($field->handle() === 'country') {
71+
return $this->country()?->extra()['name'];
72+
}
73+
74+
return $value;
75+
})
76+
->filter()
77+
->implode(', ');
78+
}
79+
80+
public function __get(string $name)
81+
{
82+
return $this->address[$name] ?? null;
83+
}
84+
85+
public static function blueprint(): \Statamic\Fields\Blueprint
86+
{
87+
$fields = [
88+
'name' => [
89+
'type' => 'text',
90+
'display' => __('Name'),
91+
'listable' => false,
92+
'width' => 50,
93+
],
94+
'line_1' => [
95+
'type' => 'text',
96+
'display' => __('Address Line 1'),
97+
'listable' => false,
98+
'width' => 50,
99+
],
100+
'line_2' => [
101+
'type' => 'text',
102+
'display' => __('Address Line 2'),
103+
'listable' => false,
104+
'width' => 50,
105+
],
106+
'city' => [
107+
'type' => 'text',
108+
'display' => __('Town/City'),
109+
'listable' => false,
110+
'width' => 50,
111+
],
112+
'postcode' => [
113+
'type' => 'text',
114+
'display' => __('Postcode'),
115+
'listable' => false,
116+
'width' => 50,
117+
],
118+
'country' => [
119+
'type' => 'dictionary',
120+
'dictionary' => ['type' => 'countries', 'emojis' => false],
121+
'max_items' => 1,
122+
'display' => __('Country'),
123+
'listable' => false,
124+
'width' => 50,
125+
],
126+
'state' => [
127+
'type' => 'states',
128+
'from' => 'country',
129+
'display' => __('State/County'),
130+
'listable' => false,
131+
'max_items' => 1,
132+
'width' => 50,
133+
],
134+
];
135+
136+
$fields = (new self)->runHooksWith('fields', ['fields' => $fields])?->fields;
137+
138+
return Blueprint::makeFromFields($fields);
71139
}
72140
}

src/Data/HasAddresses.php

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
namespace DuncanMcClean\Cargo\Data;
44

5-
use Illuminate\Support\Arr;
6-
75
trait HasAddresses
86
{
97
public function taxableAddress(): ?Address
@@ -21,32 +19,12 @@ public function taxableAddress(): ?Address
2119

2220
public function shippingAddress(): Address
2321
{
24-
$address = $this->get('shipping_address', []);
25-
26-
return new Address(
27-
name: Arr::get($address, 'name'),
28-
line1: Arr::get($address, 'line_1'),
29-
line2: Arr::get($address, 'line_2'),
30-
city: Arr::get($address, 'city'),
31-
postcode: Arr::get($address, 'postcode'),
32-
country: Arr::get($address, 'country'),
33-
state: Arr::get($address, 'state'),
34-
);
22+
return Address::make($this->get('shipping_address', []));
3523
}
3624

3725
public function billingAddress(): Address
3826
{
39-
$address = $this->get('billing_address', []);
40-
41-
return new Address(
42-
name: Arr::get($address, 'name'),
43-
line1: Arr::get($address, 'line_1'),
44-
line2: Arr::get($address, 'line_2'),
45-
city: Arr::get($address, 'city'),
46-
postcode: Arr::get($address, 'postcode'),
47-
country: Arr::get($address, 'country'),
48-
state: Arr::get($address, 'state'),
49-
);
27+
return Address::make($this->get('billing_address', []));
5028
}
5129

5230
public function hasShippingAddress(): bool

src/Fieldtypes/Address.php

Lines changed: 5 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@
22

33
namespace DuncanMcClean\Cargo\Fieldtypes;
44

5+
use DuncanMcClean\Cargo\Data;
56
use DuncanMcClean\Cargo\Data\Address as AddressData;
67
use Statamic\Fields\Fields;
78
use Statamic\Fields\Values;
89
use Statamic\Fieldtypes\Group as GroupFieldtype;
9-
use Statamic\Support\Traits\Hookable;
1010

1111
class Address extends GroupFieldtype
1212
{
13-
use Hookable;
14-
1513
protected $selectable = false;
1614

1715
public function preload()
@@ -46,79 +44,10 @@ private function performAugmentation($value, bool $shallow)
4644

4745
public function fields(): Fields
4846
{
49-
$fields = [
50-
[
51-
'handle' => 'name',
52-
'field' => [
53-
'type' => 'text',
54-
'display' => __('Name'),
55-
'listable' => false,
56-
'width' => 50,
57-
],
58-
],
59-
[
60-
'handle' => 'line_1',
61-
'field' => [
62-
'type' => 'text',
63-
'display' => __('Address Line 1'),
64-
'listable' => false,
65-
'width' => 50,
66-
],
67-
],
68-
[
69-
'handle' => 'line_2',
70-
'field' => [
71-
'type' => 'text',
72-
'display' => __('Address Line 2'),
73-
'listable' => false,
74-
'width' => 50,
75-
],
76-
],
77-
[
78-
'handle' => 'city',
79-
'field' => [
80-
'type' => 'text',
81-
'display' => __('Town/City'),
82-
'listable' => false,
83-
'width' => 50,
84-
],
85-
],
86-
[
87-
'handle' => 'postcode',
88-
'field' => [
89-
'type' => 'text',
90-
'display' => __('Postcode'),
91-
'listable' => false,
92-
'width' => 50,
93-
],
94-
],
95-
[
96-
'handle' => 'country',
97-
'field' => [
98-
'type' => 'dictionary',
99-
'dictionary' => ['type' => 'countries', 'emojis' => false],
100-
'max_items' => 1,
101-
'display' => __('Country'),
102-
'listable' => false,
103-
'width' => 50,
104-
],
105-
],
106-
[
107-
'handle' => 'state',
108-
'field' => [
109-
'type' => 'states',
110-
'from' => 'country',
111-
'display' => __('State/County'),
112-
'listable' => false,
113-
'max_items' => 1,
114-
'width' => 50,
115-
],
116-
],
117-
];
118-
119-
$fields = $this->runHooksWith('fields', ['fields' => $fields])?->fields;
120-
121-
return new Fields($fields, $this->field()->parent(), $this->field());
47+
return Data\Address::blueprint()
48+
->fields()
49+
->setParent($this->field()->parent())
50+
->setParentField($this->field());
12251
}
12352

12453
private function normalizeValue($value): array

src/Payments/Gateways/Mollie.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,15 @@ public function setup(Cart $cart): array
9797
})
9898
->values()->all(),
9999
'billingAddress' => $cart->hasBillingAddress() ? array_filter([
100-
'streetAndNumber' => $cart->billingAddress()?->line1,
101-
'streetAdditional' => $cart->billingAddress()?->line2,
100+
'streetAndNumber' => $cart->billingAddress()?->line_1,
101+
'streetAdditional' => $cart->billingAddress()?->line_2,
102102
'postalCode' => $cart->billingAddress()?->postcode,
103103
'city' => $cart->billingAddress()?->city,
104104
'country' => Arr::get($cart->billingAddress()?->country()?->data(), 'iso2'),
105105
]) : null,
106106
'shippingAddress' => $cart->hasShippingAddress() ? array_filter([
107-
'streetAndNumber' => $cart->shippingAddress()?->line1,
108-
'streetAdditional' => $cart->shippingAddress()?->line2,
107+
'streetAndNumber' => $cart->shippingAddress()?->line_1,
108+
'streetAdditional' => $cart->shippingAddress()?->line_2,
109109
'postalCode' => $cart->shippingAddress()?->postcode,
110110
'city' => $cart->shippingAddress()?->city,
111111
'country' => Arr::get($cart->shippingAddress()?->country()?->data(), 'iso2'),

tests/Cart/CartControllerTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ public function it_updates_the_cart()
9999
$this->assertEquals('FOOBAR', $cart->get('discount_code'));
100100

101101
$shippingAddress = $cart->shippingAddress();
102-
$this->assertEquals('123 ShippingMethod St', $shippingAddress->line1);
103-
$this->assertEquals('Apt 1', $shippingAddress->line2);
102+
$this->assertEquals('123 ShippingMethod St', $shippingAddress->line_1);
103+
$this->assertEquals('Apt 1', $shippingAddress->line_2);
104104
$this->assertEquals('Shippingville', $shippingAddress->city);
105105
$this->assertEquals('12345', $shippingAddress->postcode);
106106
$this->assertEquals('US', $shippingAddress->country);

0 commit comments

Comments
 (0)