Completed
Push — master ( f5a6ee...8e0a6c )
by
unknown
15s queued 12s
created

ResourceFilter::getClientConfig()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 0
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\CKANRegistry\Model;
4
5
use InvalidArgumentException;
6
use SilverStripe\Core\Injector\Injector;
7
use SilverStripe\Forms\CompositeField;
8
use SilverStripe\Forms\FieldList;
9
use SilverStripe\Forms\FormField;
10
use SilverStripe\Forms\ListboxField;
11
use SilverStripe\Forms\TextField;
12
use SilverStripe\ORM\DataObject;
13
use SilverStripe\ORM\FieldType\DBField;
14
use SilverStripe\ORM\ManyManyList;
15
16
/**
17
 * Represents a filter for a data resource, which accepts user inputted data and generates a query string (?key=value)
18
 * to use in a request against a CKAN API for that particular resource in order to filter the results shown in a
19
 * representation of that data.
20
 *
21
 * @property string FilterLabel
22
 * @property bool AllColumns
23
 * @property int Order
24
 * @method Resource FilterFor
25
 * @method ManyManyList FilterFields
26
 */
27
class ResourceFilter extends DataObject
28
{
29
    private static $table_name = 'CKANFilter_Text';
0 ignored issues
show
introduced by
The private property $table_name is not used, and could be removed.
Loading history...
30
31
    private static $db = [
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
32
        'FilterLabel' => 'Varchar',
33
        'AllColumns' => 'Boolean(1)',
34
        'Order' => 'Int',
35
    ];
36
37
    private static $defaults = [
0 ignored issues
show
introduced by
The private property $defaults is not used, and could be removed.
Loading history...
38
        'AllColumns' => true,
39
        'FilterLabel' => '',
40
    ];
41
42
    private static $has_one = [
0 ignored issues
show
introduced by
The private property $has_one is not used, and could be removed.
Loading history...
43
        'FilterFor' => Resource::class,
44
    ];
45
46
    private static $many_many = [
0 ignored issues
show
introduced by
The private property $many_many is not used, and could be removed.
Loading history...
47
        'FilterFields' => ResourceField::class,
48
    ];
49
50
    private static $summary_fields = [
0 ignored issues
show
introduced by
The private property $summary_fields is not used, and could be removed.
Loading history...
51
        'FilterLabel',
52
        'Type',
53
        'Columns',
54
    ];
55
56
    private static $singular_name = 'Text';
0 ignored issues
show
introduced by
The private property $singular_name is not used, and could be removed.
Loading history...
57
58
    /**
59
     * Defines the type of {@link FormField} that will be used to render the filter in the CMS. This is defined
60
     * in subclasses. Filters will render as TextFields by default.
61
     *
62
     * @var FormField
63
     */
64
    protected $fieldType = TextField::class;
65
66
    public function getCMSFields()
67
    {
68
        $this->beforeUpdateCMSFields(function (FieldList $fields) {
69
            $allColumnsField = $fields->dataFieldByName('AllColumns');
70
            $allColumnsField->addExtraClass('ckan-columns__all-columns');
71
72
            // Remove the scaffolded Filter Fields tab and the AllColumns field
73
            $fields->removeByName(['FilterFields', 'AllColumns']);
74
75
            // Add a composite field containing the "All columns" checkbox and the "Columns source(s)" checkbox
76
            $filterFields = ListboxField::create(
77
                'FilterFields',
78
                '',
79
                $this->FilterFor()->Fields()->map('ID', 'ReadableLabel')
80
            );
81
            $filterFields->addExtraClass('ckan-columns__filter-fields');
82
83
            $columnSources = CompositeField::create($allColumnsField, $filterFields);
84
            $columnSources
85
                ->setTitle(_t(__CLASS__ . '.COLUMNS_SOURCES', 'Columns source(s)'))
86
                ->addExtraClass('ckan-columns__sources');
87
            $fields->addFieldToTab('Root.Main', $columnSources);
88
89
            $fields->removeByName([
90
                'FilterForID',
91
                'Order',
92
            ]);
93
94
            // See https://github.com/silverstripe/silverstripe-framework/issues/8696
95
            foreach (['AllColumns', 'FilterLabel'] as $fieldName) {
96
                $field = $fields->dataFieldByName($fieldName);
97
                $field->setTitle(ucfirst(strtolower($field->Title())));
98
            }
99
        });
100
101
        return parent::getCMSFields();
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     *
107
     * @throws InvalidArgumentException If the provided Type is not an instance of FormField
108
     */
109
    public function forTemplate()
110
    {
111
        $field = Injector::inst()->createWithArgs($this->fieldType, [$this->Name]);
0 ignored issues
show
Bug Best Practice introduced by
The property Name does not exist on SilverStripe\CKANRegistry\Model\ResourceFilter. Since you implemented __get, consider adding a @property annotation.
Loading history...
112
        if (!$field instanceof FormField) {
113
            throw new InvalidArgumentException("$this->fieldType is not a FormField");
114
        }
115
        return $field;
116
    }
117
118
    /**
119
     * Returns the type of the filter, used for summary fields
120
     *
121
     * @return string
122
     */
123
    public function getType()
124
    {
125
        return $this->singular_name();
126
    }
127
128
    /**
129
     * Return a "schema" that can be provided to client side JavaScript components for client side rendering
130
     *
131
     * @return array
132
     */
133
    public function getClientConfig()
134
    {
135
        return [
136
            'label' => $this->FilterLabel,
137
            'allColumns' => $this->AllColumns,
138
            'columns' => $this->AllColumns ? null : array_map(function (ResourceField $field) {
139
                return [
140
                    'label' => $field->ReadableLabel,
141
                    'target' => $field->OriginalLabel,
142
                ];
143
            }, $this->FilterFields()->toArray()),
144
        ];
145
    }
146
147
    /**
148
     * Returns either the selected column's readable label value, or a fixed string representing multiple columns
149
     * having been selected.
150
     *
151
     * @return string|DBField
152
     */
153
    public function getColumns()
154
    {
155
        if ($this->AllColumns) {
156
            return DBField::create_Field(
157
                'HTMLFragment',
158
                '<span class="ckan-columns--all-columns">'
159
                . _t(__CLASS__ . '.ALL_COLUMNS', 'All columns')
160
                . '</span>'
161
            );
162
        }
163
164
        if (!$this->FilterFields()->count()) {
165
            return '';
166
        }
167
168
        if ($this->FilterFields()->count() === 1) {
169
            return (string) $this->FilterFields()->first()->ReadableLabel;
170
        }
171
172
        return DBField::create_Field(
173
            'HTMLFragment',
174
            '<span class="ckan-columns--multiple">'
175
            . _t(__CLASS__ . '.MULTIPLE_COLUMNS', 'Multiple columns')
176
            . '</span>'
177
        );
178
    }
179
}
180