Issues (48)

src/GridFieldSaveAllButton.php (4 issues)

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