Passed
Push — master ( ed64cb...98de9f )
by Thomas
02:50
created

setExtraFields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
namespace LeKoala\Tabulator;
4
5
use Exception;
6
use SilverStripe\ORM\DataObject;
7
use SilverStripe\View\ArrayData;
8
use SilverStripe\ORM\RelationList;
9
use SilverStripe\Control\Controller;
10
use SilverStripe\Control\HTTPRequest;
11
use SilverStripe\Control\HTTPResponse;
12
use LeKoala\FormElements\BsAutocompleteField;
13
14
/**
15
 * This component provides a autocomplete field to link element to the grid
16
 */
17
class TabulatorAddExistingAutocompleter extends AbstractTabulatorTool
18
{
19
    /**
20
     * @config
21
     */
22
    private static array $allowed_actions = [
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
23
        'add',
24
        'autocomplete',
25
    ];
26
27
28
    protected string $name = 'add_existing';
29
    protected array $extraFields = [];
30
    protected array $searchFilters = [];
31
    protected ?BsAutocompleteField $autocompleteField = null;
32
33
    public function forTemplate()
34
    {
35
        $grid = $this->tabulatorGrid;
36
        $singleton = singleton($grid->getModelClass());
37
        $context = [];
38
        if ($grid->getList() instanceof RelationList) {
39
            $record = $grid->getForm()->getRecord();
40
            if ($record && $record instanceof DataObject) {
0 ignored issues
show
introduced by
$record is always a sub-type of SilverStripe\ORM\DataObject.
Loading history...
41
                $context['Parent'] = $record;
42
            }
43
        }
44
45
        if (!$singleton->canCreate(null, $context)) {
46
            return false;
47
        }
48
49
        if (!$this->buttonName) {
50
            // provide a default button name, can be changed by calling {@link setButtonName()} on this component
51
            $this->buttonName = _t('SilverStripe\\Forms\\GridField\\GridField.LinkExisting', "Link Existing");
52
        }
53
54
        $data = new ArrayData([
55
            'ButtonName' => $this->buttonName,
56
            'ButtonClasses' => 'btn-outline-secondary font-icon-link',
57
            'Icon' => $this->isAdmini() ? 'link' : '',
58
            'AddToLink' => $this->Link('add'),
59
            'AutocompleteField' => $this->getAutocompleteField(),
60
        ]);
61
        return $this->renderWith($this->getViewerTemplates(), $data);
0 ignored issues
show
Bug introduced by
$data of type SilverStripe\View\ArrayData is incompatible with the type array expected by parameter $customFields of SilverStripe\View\ViewableData::renderWith(). ( Ignorable by Annotation )

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

61
        return $this->renderWith($this->getViewerTemplates(), /** @scrutinizer ignore-type */ $data);
Loading history...
62
    }
63
64
    /**
65
     * Note: this require the field to be bound to a form before being used
66
     * otherwise calls to Link() will fail
67
     *
68
     * @return BsAutocompleteField
69
     */
70
    public function getAutocompleteField(): BsAutocompleteField
71
    {
72
        if (!$this->autocompleteField) {
73
            $this->autocompleteField = $this->createAutocompleteField();
74
        }
75
        return $this->autocompleteField;
76
    }
77
78
    protected function createAutocompleteField(): BsAutocompleteField
79
    {
80
        $grid = $this->tabulatorGrid;
81
82
        $field = new BsAutocompleteField('autocomplete', _t('SilverStripe\\Forms\\GridField\\GridField.Find', "Find"));
83
        $field->setForm($grid->getForm());
84
        $field->setPlaceholder(_t('SilverStripe\\Forms\\GridField\\GridField.Find', "Find"));
85
        $field->setAjax(Controller::join_links($grid->Link('tool'), $this->name, 'autocomplete'));
86
        $field->setAjaxWizard($grid->getModelClass());
87
        $field->setAjaxFilters($this->searchFilters);
88
        return $field;
89
    }
90
91
    public function add(HTTPRequest $request): HTTPResponse
92
    {
93
        $response = new HTTPResponse();
94
95
        try {
96
            $RecordID = $request->postVar('RecordID');
97
            if (!$RecordID) {
98
                throw new Exception("No RecordID");
99
            }
100
101
            $modelClass = $this->tabulatorGrid->getModelClass();
102
            $record = $modelClass::get_by_id($RecordID);
103
            if (!$record) {
104
                throw new Exception("Record not found");
105
            }
106
107
            $this->tabulatorGrid->getDataList()->add($record, $this->extraFields);
0 ignored issues
show
Unused Code introduced by
The call to SilverStripe\ORM\DataList::add() has too many arguments starting with $this->extraFields. ( Ignorable by Annotation )

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

107
            $this->tabulatorGrid->getDataList()->/** @scrutinizer ignore-call */ add($record, $this->extraFields);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
108
109
            $body = json_encode([
110
                'success' => true,
111
                'message' => $record->getTitle() . " add to the list",
112
            ]);
113
            $response->setBody($body);
114
            $response->addHeader('Content-Type', 'application/json');
115
        } catch (Exception $ex) {
116
            $response->setStatusCode(500);
117
            $response->setBody($ex->getMessage());
118
        }
119
120
        return $response;
121
    }
122
123
    public function autocomplete(HTTPRequest $request): HTTPResponse
124
    {
125
        // delegate to field
126
        $acField = $this->getAutocompleteField();
127
128
        try {
129
            $response = $acField->autocomplete($request);
130
        } catch (Exception $ex) {
131
            $response = new HTTPResponse();
132
            $response->setStatusCode(500);
133
            $response->setBody($ex->getMessage());
134
        }
135
136
        return $response;
137
    }
138
139
    public function getSearchFilters(): array
140
    {
141
        return $this->searchFilters;
142
    }
143
144
    public function setSearchFilters(array $searchFilters): self
145
    {
146
        $this->searchFilters = $searchFilters;
147
        return $this;
148
    }
149
150
    /**
151
     * Get the value of extraFields
152
     */
153
    public function getExtraFields(): array
154
    {
155
        return $this->extraFields;
156
    }
157
158
    /**
159
     * Set the value of extraParams
160
     */
161
    public function setExtraFields(array $extraFields): self
162
    {
163
        $this->extraFields = $extraFields;
164
        return $this;
165
    }
166
}
167