Passed
Push — 1.0 ( eebb8e...edc40b )
by Morven
01:33
created

RegionSelectionField::Field()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

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

114
            ->setAttribute("data-region-field", /** @scrutinizer ignore-type */ true)
Loading history...
115
            ->setAttribute("data-country-field", $field->ID())
116
            ->setAttribute("data-link", $this->Link("regionslist"));
117
        
118
        if ($this->getHasEmptyDefault()) {
119
            $this->setAttribute("data-empty-string", $this->getEmptyString());
120
        }
121
122
        return parent::Field($properties);
123
    }
124
125
    /**
126
     * Get a list of regions, filtered by the provided country code
127
     * 
128
     * @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...
129
     */
130
    public function getList($country)
131
    {
132
        return Region::get()
133
            ->filter("CountryCode", strtoupper($country));
134
    }
135
136
    /**
137
     * Return a list of regions based on the supplied country ID 
138
     * 
139
     * @return string
140
     */
141
    public function regionslist()
142
    {
143
        $id = $this->getRequest()->param("ID");
144
        $data = $this->getList($id)->map("Code", "Name")->toArray();
145
146
        return json_encode($data);
147
    }
148
}