Address::getRequiredFields()   A
last analyzed

Complexity

Conditions 6
Paths 4

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 10
c 0
b 0
f 0
nc 4
nop 0
dl 0
loc 20
rs 9.2222
1
<?php
2
3
namespace SilverShop\Model;
4
5
use SilverShop\ORM\FieldType\ShopCountry;
6
use SilverStripe\Forms\DropdownField;
7
use SilverStripe\Forms\FieldList;
8
use SilverStripe\Forms\ReadonlyField;
9
use SilverStripe\Forms\TextField;
10
use SilverStripe\ORM\DataList;
11
use SilverStripe\ORM\DataObject;
12
use SilverStripe\ORM\HasManyList;
13
use SilverStripe\Security\Member;
14
use SilverStripe\SiteConfig\SiteConfig;
15
16
/**
17
 * Address model using a generic format for storing international addresses.
18
 *
19
 * Typical Address Hierarcy:
20
 *    Continent
21
 *    Country
22
 *    State / Province / Territory (Island?)
23
 *    District / Suburb / County / City
24
 *        Code / Zip (may cross over the above)
25
 *    Street / Road - name + type: eg Gandalf Cresent
26
 *    (Premises/Building/Unit/Suite)
27
 *        (Floor/Level/Side/Wing)
28
 *    Number / Entrance / Room
29
 *    Person(s), Company, Department
30
 *
31
 * Collection of international address formats:
32
 *
33
 * @see http://bitboost.com/ref/international-address-formats.html
34
 *      xAL address standard:
35
 * @see https://www.oasis-open.org/committees/ciq/ciq.html#6
36
 *      Universal Postal Union addressing standards:
37
 * @see http://www.upu.int/nc/en/activities/addressing/standards.html
38
 *
39
 * @property ShopCountry $Country
40
 * @property string $State
41
 * @property string $City
42
 * @property string $PostalCode
43
 * @property string $Address
44
 * @property string $AddressLine2
45
 * @property string $Company
46
 * @property string $FirstName
47
 * @property string $Surname
48
 * @property string $Phone
49
 * @method   Member Member()
50
 * @method   Order[]|HasManyList ShippingAddressOrders()
51
 * @method   Order[]|HasManyList BillingAddressOrders()
52
 */
53
class Address extends DataObject
54
{
55
    private static $db = [
56
        'Country' => 'ShopCountry',
57
        //level1: Country = ISO 2-character country code
58
        'State' => 'Varchar(100)',
59
        //level2: Locality, Administrative Area, State, Province, Region, Territory, Island
60
        'City' => 'Varchar(100)',
61
        //level3: Dependent Locality, City, Suburb, County, District
62
        'PostalCode' => 'Varchar(20)',
63
        //code: ZipCode, PostCode (could cross above levels within a country)
64
65
        'Address' => 'Varchar(255)',
66
        //Number + type of thoroughfare/street. P.O. box
67
        'AddressLine2' => 'Varchar(255)',
68
        //Premises, Apartment, Building. Suite, Unit, Floor, Level, Side, Wing.
69
70
        'Company' => 'Varchar(100)',
71
        //Business, Organisation, Group, Institution.
72
73
        'FirstName' => 'Varchar(100)',
74
        //Individual, Person, Contact, Attention
75
        'Surname' => 'Varchar(100)',
76
        'Phone' => 'Varchar(100)',
77
    ];
78
79
    private static $has_one = [
80
        'Member' => Member::class,
81
    ];
82
83
    private static $has_many = [
84
        'ShippingAddressOrders' => Order::class . '.ShippingAddress',
85
        'BillingAddressOrders' => Order::class . '.BillingAddress'
86
    ];
87
88
    private static $casting = [
89
        'Country' => ShopCountry::class,
90
    ];
91
92
    private static $required_fields = [
93
        'Country',
94
        'State',
95
        'City',
96
        'Address',
97
    ];
98
99
    private static $summary_fields = [
100
        'toString' => 'Address',
101
    ];
102
103
    private static $table_name = 'SilverShop_Address';
104
105
    public function getCMSFields()
106
    {
107
        $self = $this;
108
109
        $this->beforeUpdateCMSFields(
110
            function (FieldList $fields) use ($self) {
111
                $fields->addFieldToTab(
112
                    'Root.Main',
113
                    $self->getCountryField(),
114
                    'State'
115
                );
116
117
                $fields->removeByName('MemberID');
118
            }
119
        );
120
121
        return parent::getCMSFields();
122
    }
123
124
    public function getFrontEndFields($params = null)
125
    {
126
        $fields = new FieldList(
127
            $this->getCountryField(),
128
            TextField::create('Company', $this->fieldLabel('Company')),
129
            $addressfield = TextField::create('Address', $this->fieldLabel('Address')),
130
            $address2field =
131
                TextField::create('AddressLine2', $this->fieldLabel('AddressLine2')),
132
            $cityfield = TextField::create('City', $this->fieldLabel('City')),
133
            $statefield = TextField::create('State', $this->fieldLabel('State')),
134
            $postcodefield = TextField::create('PostalCode', $this->fieldLabel('PostalCode')),
135
            $phonefield = TextField::create('Phone', $this->fieldLabel('Phone'))
136
        );
137
        if (!empty($params['addfielddescriptions'])) {
138
            $addressfield->setDescription(
139
                _t(__CLASS__ . '.AddressHint', 'street / thoroughfare number, name, and type or P.O. Box')
140
            );
141
            $address2field->setDescription(
142
                _t(__CLASS__ . '.AddressLine2Hint', 'premises, building, apartment, unit, floor')
143
            );
144
            $cityfield->setDescription(_t(__CLASS__ . '.CityHint', 'or suburb, county, district'));
145
            $statefield->setDescription(_t(__CLASS__ . '.StateHint', 'or province, territory, island'));
146
        }
147
148
        $this->extend('updateFormFields', $fields);
149
        return $fields;
150
    }
151
152
    public function getCountryField()
153
    {
154
        $countries = SiteConfig::current_site_config()->getCountriesList();
155
        if (count($countries) == 1) {
156
            //field name is Country_readonly so it's value doesn't get updated
157
            return ReadonlyField::create(
158
                'Country_readonly',
159
                $this->fieldLabel('Country'),
160
                array_pop($countries)
161
            );
162
        }
163
        $field = DropdownField::create(
164
            'Country',
165
            $this->fieldLabel('Country'),
166
            $countries
167
        )->setHasEmptyDefault(true);
168
169
        $this->extend('updateCountryField', $field);
170
171
        return $field;
172
    }
173
174
    /**
175
     * Get an array of data fields that must be populated for model to be valid.
176
     * Required fields can be customised via self::$required_fields
177
     */
178
    public function getRequiredFields()
179
    {
180
        $fields = self::config()->required_fields;
181
        //hack to allow overriding arrays in ss config
182
        if (self::$required_fields != $fields) {
183
            foreach (self::$required_fields as $requirement) {
184
                if (($key = array_search($requirement, $fields)) !== false) {
185
                    unset($fields[$key]);
186
                }
187
            }
188
        }
189
        //set nicer keys for easier processing
190
        $fields = array_combine($fields, $fields);
191
        $this->extend('updateRequiredFields', $fields);
192
        //don't require country if shop config only specifies a single country
193
        if (isset($fields['Country']) && SiteConfig::current_site_config()->getSingleCountry()) {
194
            unset($fields['Country']);
195
        }
196
197
        return $fields;
198
    }
199
200
    /**
201
     * Get full name associated with this Address
202
     */
203
    public function getName()
204
    {
205
        return implode(
206
            ' ',
207
            array_filter(
208
                [
209
                    $this->FirstName,
210
                    $this->Surname,
211
                ]
212
            )
213
        );
214
    }
215
216
    /**
217
     * Convert address to a single string.
218
     */
219
    public function toString($separator = ', ')
220
    {
221
        $fields = [
222
            $this->Company,
223
            $this->getName(),
224
            $this->Address,
225
            $this->AddressLine2,
226
            $this->City,
227
            $this->State,
228
            $this->PostalCode,
229
            $this->Country
230
        ];
231
        $this->extend('updateToString', $fields);
232
        return implode($separator, array_filter($fields));
233
    }
234
235
    public function getTitle()
236
    {
237
        return $this->toString();
238
    }
239
240
    public function forTemplate()
241
    {
242
        return $this->renderWith(__CLASS__);
243
    }
244
245
    /**
246
     * Add alias setters for fields which are synonymous
247
     *
248
     * @param  string $val
249
     * @return $this
250
     */
251
    public function setProvince($val)
252
    {
253
        $this->State = $val;
254
        return $this;
255
    }
256
257
    public function setTerritory($val)
258
    {
259
        $this->State = $val;
260
        return $this;
261
    }
262
263
    public function setIsland($val)
264
    {
265
        $this->State = $val;
266
        return $this;
267
    }
268
269
    public function setPostCode($val)
270
    {
271
        $this->PostalCode = $val;
272
        return $this;
273
    }
274
275
    public function setZipCode($val)
276
    {
277
        $this->PostalCode = $val;
278
        return $this;
279
    }
280
281
    public function setStreet($val)
282
    {
283
        $this->Address = $val;
284
        return $this;
285
    }
286
287
    public function setStreet2($val)
288
    {
289
        $this->AddressLine2 = $val;
290
        return $this;
291
    }
292
293
    public function setAddress2($val)
294
    {
295
        $this->AddressLine2 = $val;
296
        return $this;
297
    }
298
299
    public function setInstitution($val)
300
    {
301
        $this->Company = $val;
302
        return $this;
303
    }
304
305
    public function setBusiness($val)
306
    {
307
        $this->Company = $val;
308
        return $this;
309
    }
310
311
    public function setOrganisation($val)
312
    {
313
        $this->Company = $val;
314
        return $this;
315
    }
316
317
    public function setOrganization($val)
318
    {
319
        $this->Company = $val;
320
        return $this;
321
    }
322
323
    function validate()
324
    {
325
        $result = parent::validate();
326
327
        foreach ($this->getRequiredFields() as $requirement) {
328
            if (empty($this->$requirement)) {
329
                $result->addError("Address Model validate function - missing required field: $requirement");
330
            }
331
        }
332
333
        return $result;
334
    }
335
}
336