GridFieldSaveAllButton::setUseHandleSave()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace LeKoala\CmsActions;
4
5
use SilverStripe\Control\Controller;
6
use SilverStripe\Control\Director;
7
use SilverStripe\Forms\GridField\GridField;
8
use SilverStripe\ORM\DataList;
9
use SilverStripe\ORM\DataObject;
10
use Exception;
11
use SilverStripe\Control\HTTPResponse;
12
13
/**
14
 * When using inline editing on a ModelAdmin, there is no save button
15
 * This allows saving the records
16
 * It needs a custom endpoint because somehow, new records are not sent along
17
 */
18
class GridFieldSaveAllButton extends GridFieldTableButton
19
{
20
    protected $fontIcon = 'save';
21
    public bool $submitData = true;
22
    /**
23
     * @var boolean
24
     */
25
    protected $noAjax = false;
26
    protected ?string $completeMessage = null;
27
    protected ?bool $useHandleSave = true;
28
    protected $allowEmptyResponse = true;
29
    protected bool $shouldReload = false;
30
31
    /**
32
     * @param string $targetFragment
33
     * @param mixed $buttonLabel
34
     */
35
    public function __construct($targetFragment = 'buttons-before-left', $buttonLabel = null)
36
    {
37
        parent::__construct($targetFragment, $buttonLabel);
38
        $this->buttonLabel = $buttonLabel ?? _t('GridFieldSaveAllButton.SaveAll', 'Save all');
39
    }
40
41
    /**
42
     * @param GridField $gridField
43
     * @param Controller $controller
44
     * @param array $arguments
45
     * @param array $data
46
     * @return ?HTTPResponse
47
     */
48
    public function handle(GridField $gridField, Controller $controller, $arguments = [], $data = [])
49
    {
50
        $fieldName = $gridField->getName();
51
        $list = $gridField->getList();
52
        $model = $gridField->getModelClass();
53
54
        // Without this, handleSave does not work
55
        $gridField->setSubmittedValue($data[$fieldName]);
56
57
        if (!($list instanceof DataList)) {
58
            throw new Exception("Requires a DataList");
59
        }
60
61
        $updatedData = $data[$fieldName]['GridFieldEditableColumns'] ?? [];
62
        foreach ($updatedData as $id => $values) {
63
            $record = $list->byID($id);
64
            if (!$record) {
65
                continue;
66
            }
67
            // You can use the grid field component or a simple loop with write
68
            if ($this->useHandleSave) {
69
                /** @var \Symbiote\GridFieldExtensions\GridFieldEditableColumns $component */
70
                $component = $gridField->getConfig()->getComponentByType(\Symbiote\GridFieldExtensions\GridFieldEditableColumns::class);
0 ignored issues
show
Bug introduced by
The type Symbiote\GridFieldExtens...ridFieldEditableColumns 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...
71
                $component->handleSave($gridField, $record);
72
            } else {
73
                foreach ($values as $k => $v) {
74
                    $record->$k = $v;
75
                }
76
                $record->write();
77
            }
78
        }
79
        $newData = $data[$fieldName]['GridFieldAddNewInlineButton'] ?? [];
80
        foreach ($newData as $idx => $values) {
81
            $record = new $model;
82
            if ($this->useHandleSave) {
83
                /** @var \Symbiote\GridFieldExtensions\GridFieldAddNewInlineButton $component */
84
                $component = $gridField->getConfig()->getComponentByType(\Symbiote\GridFieldExtensions\GridFieldAddNewInlineButton::class);
0 ignored issues
show
Bug introduced by
The type Symbiote\GridFieldExtens...FieldAddNewInlineButton 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...
85
                $component->handleSave($gridField, $record);
86
            } else {
87
                foreach ($values as $k => $v) {
88
                    $record->$k = $v;
89
                }
90
            }
91
            $record->write();
92
        }
93
94
        $response = $controller->getResponse();
95
96
        if (Director::is_ajax()) {
97
            if (!$this->completeMessage) {
98
                $this->completeMessage = _t('GridFieldSaveAllButton.DONE', 'All saved');
99
            }
100
            if ($this->shouldReload) {
101
                ActionsGridFieldItemRequest::addXReload($controller);
102
            }
103
            $response->addHeader('X-Status', rawurlencode($this->completeMessage));
104
            return null;
105
        } else {
106
            return $controller->redirectBack();
107
        }
108
    }
109
110
    /**
111
     * Get the value of completeMessage
112
     */
113
    public function getCompleteMessage(): string
114
    {
115
        return $this->completeMessage;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->completeMessage could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
116
    }
117
118
    /**
119
     * Set the value of completeMessage
120
     *
121
     * @param string $completeMessage
122
     */
123
    public function setCompleteMessage($completeMessage): self
124
    {
125
        $this->completeMessage = $completeMessage;
126
        return $this;
127
    }
128
129
    /**
130
     * Get the value of useHandleSave
131
     */
132
    public function getUseHandleSave(): bool
133
    {
134
        return $this->useHandleSave;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->useHandleSave could return the type null which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
135
    }
136
137
    /**
138
     * Set the value of useHandleSave
139
     *
140
     * @param bool $useHandleSave
141
     */
142
    public function setUseHandleSave($useHandleSave): self
143
    {
144
        $this->useHandleSave = $useHandleSave;
145
        return $this;
146
    }
147
148
    /**
149
     * Get the value of shouldReload
150
     */
151
    public function getShouldReload(): bool
152
    {
153
        return $this->shouldReload;
154
    }
155
156
    /**
157
     * Set the value of shouldReload
158
     *
159
     * @param bool $shouldReload
160
     */
161
    public function setShouldReload($shouldReload): self
162
    {
163
        $this->shouldReload = $shouldReload;
164
        return $this;
165
    }
166
}
167