RegionSelectionField   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 175
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 15
eloc 63
c 4
b 0
f 0
dl 0
loc 175
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getSource() 0 17 3
A Field() 0 23 2
A setCountryField() 0 5 1
A __construct() 0 6 1
A getList() 0 23 4
A getCountryField() 0 3 1
A setCreateEmptyDefault() 0 5 1
A regionslist() 0 12 1
A getCreateEmptyDefault() 0 3 1
1
<?php
2
3
namespace SilverCommerce\GeoZones\Forms;
4
5
use Locale;
6
use SilverCommerce\GeoZones\Helpers\GeoZonesHelper;
7
use SilverStripe\i18n\i18n;
8
use SilverStripe\ORM\ArrayList;
9
use SilverStripe\View\Requirements;
10
use SilverStripe\Forms\DropdownField;
11
use SilverCommerce\GeoZones\Model\Region;
12
use SilverStripe\View\ArrayData;
13
14
/**
15
 * Custom field that makes use of Ajax to change the list of possible regions you can select.
16
 * 
17
 * This field needs to be linked with another field on the same form that will provide the
18
 * selected country code. EG:
19
 * 
20
 *  $field = RegionSelectField::create("FieldName", "FieldTitle", "CountryFieldName");
21
 */
22
class RegionSelectionField extends DropdownField
23
{    
24
    private static $allowed_actions = [
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
25
        "regionslist"
26
    ];
27
28
    private static $url_handlers = array(
0 ignored issues
show
introduced by
The private property $url_handlers is not used, and could be removed.
Loading history...
29
        '$Action!/$ID' => '$Action'
30
    );
31
32
    /**
33
     * The name of the associated country field
34
     * 
35
     * @var string
36
     */
37
    private $country_field;
38
39
    protected $create_empty_default = true;
40
41
    /**
42
     * Get the associated country field
43
     */ 
44
    public function getCountryField()
45
    {
46
        return $this->country_field;
47
    }
48
49
    /**
50
     * Set the associated country field
51
     *
52
     * @return  self
53
     */ 
54
    public function setCountryField($country_field)
55
    {
56
        $this->country_field = $country_field;
57
58
        return $this;
59
    }
60
61
    /**
62
     * Overwrite default get source to return
63
     * custom list of regions
64
     * 
65
     * @return array|ArrayAccess
0 ignored issues
show
Bug introduced by
The type SilverCommerce\GeoZones\Forms\ArrayAccess was not found. Did you mean ArrayAccess? If so, make sure to prefix the type with \.
Loading history...
66
     */
67
    public function getSource()
68
    {
69
        $field = $this
70
            ->getForm()
71
            ->Fields()
72
            ->dataFieldByName($this->country_field);
73
74
        if (empty($field) || empty($field->Value())) {
75
            $locale = strtoupper(Locale::getRegion(i18n::get_locale()));
76
        } else {
77
            $locale = $field->Value();
78
        }
79
80
        return $this
81
            ->getList($locale)
82
            ->map("Code", "Name")
83
            ->toArray();
84
    }
85
86
    /**
87
     * Custom constructor to allow us to define the associated country field
88
     * 
89
     * @param string $name the name of this field
90
     * @param string $title the title (label) of this field
91
     * @param string $country_field The name of the country select field in this form
92
     * @param string $value pass the value of this field
93
     */
94
    public function __construct($name, $title = null, $country_field = "Country", $value = null)
95
    {
96
        // Force construction of parent
97
        parent::__construct($name, $title, [], $value);
98
99
        $this->country_field = $country_field;
100
    }
101
102
    /**
103
     * Render the final field
104
     */
105
    public function Field($properties = [])
106
    {
107
        Requirements::javascript("silvercommerce/geozones: client/dist/js/RegionSelectionField.min.js");
108
109
        $country_field = $this->country_field;
110
        
111
        // Get source based on selected country (or current/default locale)
112
        $field = $this
113
            ->getForm()
114
            ->Fields()
115
            ->dataFieldByName($country_field);
116
        
117
        // Add reference to base field
118
        $this
119
            ->setAttribute("data-region-field", true)
120
            ->setAttribute("data-country-field", $field->ID())
121
            ->setAttribute("data-link", $this->Link("regionslist"));
122
        
123
        if ($this->getHasEmptyDefault()) {
124
            $this->setAttribute("data-empty-string", $this->getEmptyString());
125
        }
126
127
        return parent::Field($properties);
128
    }
129
130
    /**
131
     * Get a list of regions, filtered by the provided country code
132
     * 
133
     * @return SSList
0 ignored issues
show
Bug introduced by
The type SilverCommerce\GeoZones\Forms\SSList was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
134
     */
135
    public function getList($country)
136
    {
137
        $list = GeoZonesHelper::create([strtoupper($country)])
138
            ->getRegionsAsObjects();
139
140
        // If there is no region available, create an empty dummy 
141
        if (!$list->exists() && $this->getCreateEmptyDefault()) {
142
            $countries = i18n::getData()->getCountries();
143
            if (isset($countries[strtolower($country)])) {
144
                $name = $countries[strtolower($country)];
145
            } else {
146
                $name = $country;
147
            }
148
            $list = ArrayList::create();
149
            $list->push(ArrayData::create([
150
                "Name" => $name,
151
                "Type" => "Nation",
152
                "Code" => strtoupper($country),
153
                "CountryCode" => strtoupper($country)
154
            ]));
155
        }
156
157
        return $list;
158
    }
159
160
    /**
161
     * Return a list of regions based on the supplied country ID 
162
     * 
163
     * @return string
164
     */
165
    public function regionslist()
166
    {
167
        $id = $this
168
            ->getRequest()
169
            ->param("ID");
170
171
        $data = $this
172
            ->getList($id)
173
            ->map("RegionCode", "Name")
174
            ->toArray();
175
176
        return json_encode($data);
177
    }
178
179
    /**
180
     * Get the value of create_empty_default
181
     */ 
182
    public function getCreateEmptyDefault()
183
    {
184
        return $this->create_empty_default;
185
    }
186
187
    /**
188
     * Set the value of create_empty_default
189
     *
190
     * @return  self
191
     */ 
192
    public function setCreateEmptyDefault($create_empty_default)
193
    {
194
        $this->create_empty_default = $create_empty_default;
195
196
        return $this;
197
    }
198
}