Passed
Push — 1.0 ( 44527a...85af58 )
by
unknown
02:55
created

RegionSelectionField::getCreateEmptyDefault()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace SilverCommerce\GeoZones\Forms;
4
5
use Locale;
6
use SilverStripe\i18n\i18n;
7
use SilverStripe\ORM\ArrayList;
8
use SilverStripe\View\Requirements;
9
use SilverStripe\Forms\DropdownField;
10
use SilverCommerce\GeoZones\Model\Region;
11
12
/**
13
 * Custom field that makes use of Ajax to change the list of possible regions you can select.
14
 * 
15
 * This field needs to be linked with another field on the same form that will provide the
16
 * selected country code. EG:
17
 * 
18
 *  $field = RegionSelectField::create("FieldName", "FieldTitle", "CountryFieldName");
19
 */
20
class RegionSelectionField extends DropdownField
21
{    
22
    private static $allowed_actions = [
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
23
        "regionslist"
24
    ];
25
26
    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...
27
        '$Action!/$ID' => '$Action'
28
    );
29
30
    /**
31
     * The name of the associated country field
32
     * 
33
     * @var string
34
     */
35
    private $country_field;
36
37
    protected $create_empty_default = true;
38
39
    /**
40
     * Get the associated country field
41
     */ 
42
    public function getCountryField()
43
    {
44
        return $this->country_field;
45
    }
46
47
    /**
48
     * Set the associated country field
49
     *
50
     * @return  self
51
     */ 
52
    public function setCountryField($country_field)
53
    {
54
        $this->country_field = $country_field;
55
56
        return $this;
57
    }
58
59
    /**
60
     * Overwrite default get source to return
61
     * custom list of regions
62
     * 
63
     * @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...
64
     */
65
    public function getSource()
66
    {
67
        $field = $this
68
            ->getForm()
69
            ->Fields()
70
            ->dataFieldByName($this->country_field);
71
72
        if (empty($field) || empty($field->Value())) {
73
            $locale = strtoupper(Locale::getRegion(i18n::get_locale()));
74
        } else {
75
            $locale = $field->Value();
76
        }
77
78
        return $this
79
            ->getList($locale)
80
            ->map("Code", "Name")
81
            ->toArray();
82
    }
83
84
    /**
85
     * Custom constructor to allow us to define the associated country field
86
     * 
87
     * @param string $name the name of this field
88
     * @param string $title the title (label) of this field
89
     * @param string $country_field The name of the country select field in this form
90
     * @param string $value pass the value of this field
91
     */
92
    public function __construct($name, $title = null, $country_field = "Country", $value = null)
93
    {
94
        // Force construction of parent
95
        parent::__construct($name, $title, [], $value);
96
97
        $this->country_field = $country_field;
98
    }
99
100
    /**
101
     * Render the final field
102
     */
103
    public function Field($properties = [])
104
    {
105
        Requirements::javascript("silvercommerce/geozones: client/dist/js/RegionSelectionField.min.js");
106
107
        $country_field = $this->country_field;
108
        
109
        // Get source based on selected country (or current/default locale)
110
        $field = $this
111
            ->getForm()
112
            ->Fields()
113
            ->dataFieldByName($country_field);
114
        
115
        // Add reference to base field
116
        $this
117
            ->setAttribute("data-region-field", true)
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type string expected by parameter $value of SilverStripe\Forms\FormField::setAttribute(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

117
            ->setAttribute("data-region-field", /** @scrutinizer ignore-type */ true)
Loading history...
118
            ->setAttribute("data-country-field", $field->ID())
119
            ->setAttribute("data-link", $this->Link("regionslist"));
120
        
121
        if ($this->getHasEmptyDefault()) {
122
            $this->setAttribute("data-empty-string", $this->getEmptyString());
123
        }
124
125
        return parent::Field($properties);
126
    }
127
128
    /**
129
     * Get a list of regions, filtered by the provided country code
130
     * 
131
     * @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...
132
     */
133
    public function getList($country)
134
    {
135
        $list = Region::get()
136
            ->filter("CountryCode", strtoupper($country));
137
138
        if (!$list->exists() && $this->getCreateEmptyDefault()) {
139
            $countries = i18n::getData()->getCountries();
140
            if (isset($countries[strtolower($country)])) {
141
                $name = $countries[strtolower($country)];
142
            } else {
143
                $name = $country;
144
            }
145
            $list = ArrayList::create();
146
            $list->push(Region::create([
147
                "Name" => $name,
148
                "Type" => "Nation",
149
                "Code" => strtoupper($country),
150
                "CountryCode" => strtoupper($country)
151
            ]));
152
        }
153
154
        return $list;
155
    }
156
157
    /**
158
     * Return a list of regions based on the supplied country ID 
159
     * 
160
     * @return string
161
     */
162
    public function regionslist()
163
    {
164
        $id = $this->getRequest()->param("ID");
165
        $data = $this->getList($id)->map("Code", "Name")->toArray();
166
167
        return json_encode($data);
168
    }
169
170
    /**
171
     * Get the value of create_empty_default
172
     */ 
173
    public function getCreateEmptyDefault()
174
    {
175
        return $this->create_empty_default;
176
    }
177
178
    /**
179
     * Set the value of create_empty_default
180
     *
181
     * @return  self
182
     */ 
183
    public function setCreateEmptyDefault($create_empty_default)
184
    {
185
        $this->create_empty_default = $create_empty_default;
186
187
        return $this;
188
    }
189
}