1 | <?php |
||||
2 | |||||
3 | namespace ilateral\SilverStripe\ModelAdminPlus; |
||||
4 | |||||
5 | use SilverStripe\Forms\Form; |
||||
6 | use SilverStripe\ORM\ArrayList; |
||||
7 | use SilverStripe\Admin\ModelAdmin; |
||||
8 | use SilverStripe\View\Requirements; |
||||
9 | use Colymba\BulkManager\BulkManager; |
||||
10 | use SilverStripe\Core\Config\Config; |
||||
11 | use SilverStripe\Control\HTTPRequest; |
||||
12 | use SilverStripe\Forms\GridField\GridField; |
||||
13 | use Colymba\BulkManager\BulkAction\UnlinkHandler; |
||||
14 | use SilverStripe\Forms\GridField\GridFieldConfig; |
||||
15 | use SilverStripe\Forms\GridField\GridFieldButtonRow; |
||||
16 | use SilverStripe\Forms\GridField\GridFieldPaginator; |
||||
17 | use ilateral\SilverStripe\ModelAdminPlus\AutoCompleteField; |
||||
18 | use Symbiote\GridFieldExtensions\GridFieldConfigurablePaginator; |
||||
19 | use SilverStripe\Forms\GridField\GridFieldFilterHeader as SSGridFieldFilterHeader; |
||||
20 | |||||
21 | /** |
||||
22 | * Custom version of model admin that adds extra features |
||||
23 | * (such as submitting search results via a POST, saving the query |
||||
24 | * as a session and automatic Bulk Editing support) |
||||
25 | * |
||||
26 | * @author ilateral |
||||
27 | * @package ModelAdminPlus |
||||
28 | */ |
||||
29 | abstract class ModelAdminPlus extends ModelAdmin |
||||
30 | { |
||||
31 | const EXPORT_FIELDS = "export_fields"; |
||||
32 | |||||
33 | const ACTION_SUGGEST = 'suggest'; |
||||
34 | |||||
35 | /** |
||||
36 | * Automatically convert date fields on gridfields |
||||
37 | * to use `Date.Nice`. |
||||
38 | * |
||||
39 | * @var boolean |
||||
40 | */ |
||||
41 | private static $auto_convert_dates = true; |
||||
42 | |||||
43 | /** |
||||
44 | * Automatically convert DB text fields to AutoComplete fields |
||||
45 | * |
||||
46 | * @var boolean |
||||
47 | */ |
||||
48 | private static $convert_to_autocomplete = true; |
||||
0 ignored issues
–
show
introduced
by
![]() |
|||||
49 | |||||
50 | private static $allowed_actions = [ |
||||
0 ignored issues
–
show
|
|||||
51 | "SearchForm", |
||||
52 | self::ACTION_SUGGEST |
||||
53 | ]; |
||||
54 | |||||
55 | /** |
||||
56 | * List of currently registered ModelAdminSnippets, that is represented as |
||||
57 | * a list of classnames. |
||||
58 | * |
||||
59 | * These snippets are then setup when ModelAdminPlus is initilised and |
||||
60 | * rendered into the ModelAdminPlus content template. |
||||
61 | * |
||||
62 | * This list can also be a divided up by managed classnames, so that snippets will |
||||
63 | * only be loaded when accessing that class, EG: |
||||
64 | * |
||||
65 | * $registered_snippets = [ |
||||
66 | * MyObject::class => [ |
||||
67 | * MySnippetOne::class, |
||||
68 | * MySnippetTwo::class |
||||
69 | * ] |
||||
70 | * ]; |
||||
71 | * |
||||
72 | * @var array |
||||
73 | */ |
||||
74 | private static $registered_snippets = []; |
||||
75 | |||||
76 | /** |
||||
77 | * Setup snippets for current screen |
||||
78 | */ |
||||
79 | public function getSnippets() |
||||
80 | { |
||||
81 | $snippets = ArrayList::create(); |
||||
82 | $model_class = $this->getModelClass(); |
||||
83 | |||||
84 | // Setup any model admin plus snippets |
||||
85 | foreach ($this->config()->registered_snippets as $key => $value) { |
||||
86 | if (is_int($key)) { |
||||
87 | $snippet = $this->createSnippetObject($value); |
||||
88 | $snippets->add($snippet); |
||||
89 | } |
||||
90 | |||||
91 | if (is_array($value) && $key == $model_class) { |
||||
92 | foreach ($value as $snippet_class) { |
||||
93 | $snippet = $this->createSnippetObject($snippet_class); |
||||
94 | $snippets->add($snippet); |
||||
95 | } |
||||
96 | } |
||||
97 | } |
||||
98 | |||||
99 | $snippets = $snippets->sort("Order", "DESC"); |
||||
100 | |||||
101 | $this->extend("updateSnippets", $snippets); |
||||
102 | |||||
103 | return $snippets; |
||||
104 | } |
||||
105 | |||||
106 | protected function createSnippetObject(string $class): ModelAdminSnippet |
||||
107 | { |
||||
108 | $snippet = new $class('snippets-before'); |
||||
109 | $snippet->setParent($this); |
||||
110 | return $snippet; |
||||
111 | } |
||||
112 | |||||
113 | public function init() |
||||
114 | { |
||||
115 | parent::init(); |
||||
116 | |||||
117 | Requirements::add_i18n_javascript('silverstripe/cms: client/lang', false, true); |
||||
0 ignored issues
–
show
The function
SilverStripe\View\Requir...::add_i18n_javascript() has been deprecated.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
118 | |||||
119 | $clear = $this->getRequest()->getVar("clear"); |
||||
120 | |||||
121 | if (isset($clear) && $clear == 1) { |
||||
122 | $this->clearSearchSession(); |
||||
123 | // Remove clear flag |
||||
124 | return $this->redirect( |
||||
125 | $this->Link( |
||||
126 | $this->sanitiseClassName($this->modelClass) |
||||
127 | ) |
||||
128 | ); |
||||
129 | } |
||||
130 | } |
||||
131 | |||||
132 | /** |
||||
133 | * Get the default export fields for the current model. |
||||
134 | * |
||||
135 | * First this checks if there is an `export_fields` config variable set on |
||||
136 | * the model class, if not, it reverts to the default behaviour. |
||||
137 | * |
||||
138 | * @return array |
||||
139 | */ |
||||
140 | public function getExportFields() |
||||
141 | { |
||||
142 | $export_fields = Config::inst()->get( |
||||
143 | $this->modelClass, |
||||
144 | self::EXPORT_FIELDS |
||||
145 | ); |
||||
146 | |||||
147 | if (isset($export_fields) && is_array($export_fields)) { |
||||
148 | $fields = $export_fields; |
||||
149 | } else { |
||||
150 | $fields = parent::getExportFields(); |
||||
151 | } |
||||
152 | |||||
153 | $this->extend("updateExportFields", $fields); |
||||
154 | |||||
155 | return $fields; |
||||
156 | } |
||||
157 | |||||
158 | /** |
||||
159 | * Get the name of the session to be useed by this model admin's search |
||||
160 | * form. |
||||
161 | * |
||||
162 | * @return string |
||||
163 | */ |
||||
164 | public function getSearchSessionName() |
||||
165 | { |
||||
166 | $curr = $this->sanitiseClassName(self::class); |
||||
167 | $model = $this->sanitiseClassName($this->modelClass); |
||||
168 | return $curr . "." . $model; |
||||
169 | } |
||||
170 | |||||
171 | /** |
||||
172 | * Empty the current search session |
||||
173 | * |
||||
174 | * @return Session |
||||
0 ignored issues
–
show
The type
ilateral\SilverStripe\ModelAdminPlus\Session 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. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||
175 | */ |
||||
176 | public function clearSearchSession() |
||||
177 | { |
||||
178 | $session = $this->getRequest()->getSession(); |
||||
179 | return $session->clear($this->getSearchSessionName()); |
||||
180 | } |
||||
181 | |||||
182 | /** |
||||
183 | * Get the current search session |
||||
184 | * |
||||
185 | * @return Session |
||||
186 | */ |
||||
187 | public function getSearchSession() |
||||
188 | { |
||||
189 | $session = $this->getRequest()->getSession(); |
||||
190 | return $session->get($this->getSearchSessionName()); |
||||
191 | } |
||||
192 | |||||
193 | /** |
||||
194 | * Set some data to a search session. This needs to be an array of |
||||
195 | * data (like the data submitted by a form). |
||||
196 | * |
||||
197 | * @param array $data An array of data to store in the session |
||||
198 | * |
||||
199 | * @return self |
||||
200 | */ |
||||
201 | public function setSearchSession($data) |
||||
202 | { |
||||
203 | $session = $this->getRequest()->getSession(); |
||||
204 | return $session->set($this->getSearchSessionName(), $data); |
||||
205 | } |
||||
206 | |||||
207 | /** |
||||
208 | * Get the current search results, combined with any saved |
||||
209 | * search results and resturn (as an array). |
||||
210 | * |
||||
211 | * @return array |
||||
212 | */ |
||||
213 | public function getSearchData() |
||||
214 | { |
||||
215 | $data = $this->getSearchSession(); |
||||
216 | |||||
217 | if (!$data || $data && !is_array($data)) { |
||||
0 ignored issues
–
show
|
|||||
218 | $data = []; |
||||
219 | } |
||||
220 | |||||
221 | return $data; |
||||
222 | } |
||||
223 | |||||
224 | protected function getGridField(): GridField |
||||
225 | { |
||||
226 | $field = parent::getGridField(); |
||||
227 | |||||
228 | if ($this->config()->auto_convert_dates) { |
||||
229 | GridFieldDateFinder::create($field)->convertDateFields(); |
||||
230 | } |
||||
231 | |||||
232 | return $field; |
||||
233 | } |
||||
234 | |||||
235 | protected function getGridFieldConfig(): GridFieldConfig |
||||
236 | { |
||||
237 | $config = parent::getGridFieldConfig(); |
||||
238 | |||||
239 | // Add bulk editing to gridfield |
||||
240 | $manager = new BulkManager(); |
||||
241 | $manager->removeBulkAction(UnlinkHandler::class); |
||||
242 | |||||
243 | $config |
||||
244 | ->addComponent(new GridFieldSnippetRow(), GridFieldButtonRow::class) |
||||
245 | ->removeComponentsByType(GridFieldPaginator::class) |
||||
246 | ->addComponent($manager) |
||||
247 | ->addComponent(new GridFieldConfigurablePaginator()); |
||||
248 | |||||
249 | // Switch to custom filter header |
||||
250 | if ($config->getComponentsByType(SSGridFieldFilterHeader::class)->exists()) { |
||||
251 | $config |
||||
252 | ->removeComponentsByType(SSGridFieldFilterHeader::class) |
||||
253 | ->addComponent(new GridFieldFilterHeader( |
||||
254 | false, |
||||
255 | function ($context) { |
||||
256 | $this->extend('updateSearchContext', $context); |
||||
257 | }, |
||||
258 | function ($form) { |
||||
259 | $this->extend('updateSearchForm', $form); |
||||
260 | } |
||||
261 | )); |
||||
262 | } |
||||
263 | |||||
264 | // Add custom snippets |
||||
265 | foreach ($this->getSnippets() as $snippet) { |
||||
266 | $config->addComponent($snippet); |
||||
267 | } |
||||
268 | |||||
269 | return $config; |
||||
270 | } |
||||
271 | |||||
272 | /** |
||||
273 | * Find and return the recommended suggestion for an autocomplete |
||||
274 | * field |
||||
275 | * |
||||
276 | * @param array $data Submitted form |
||||
277 | * @param Form $form The current form |
||||
278 | * |
||||
279 | * @return HTTPResponse |
||||
0 ignored issues
–
show
|
|||||
280 | */ |
||||
281 | public function suggest(HTTPRequest $request) |
||||
282 | { |
||||
283 | $name = $request->param('n'); |
||||
284 | $grid = $this->getGridField(); |
||||
285 | |||||
286 | // Manually re-assign gridfield to edit form |
||||
287 | $form = $this->getEditForm(); |
||||
288 | $grid->setForm($form); |
||||
289 | |||||
290 | $config = $grid->getConfig(); |
||||
291 | /** @var GridFieldFilterHeader */ |
||||
292 | $search = $config->getComponentByType(GridFieldFilterHeader::class); |
||||
293 | $form = isset($search) ? $search->getSearchForm($grid) : null; |
||||
0 ignored issues
–
show
The method
getSearchForm() does not exist on SilverStripe\Forms\GridField\GridFieldComponent . It seems like you code against a sub-type of SilverStripe\Forms\GridField\GridFieldComponent such as SilverStripe\Forms\GridField\GridFieldFilterHeader or SilverStripe\Forms\GridField\GridFieldPrintButton or SilverStripe\Forms\GridField\GridFieldFilterHeader or SilverStripe\Forms\GridField\GridFieldPrintButton or Symbiote\GridFieldExtens...\GridFieldOrderableRows or SilverStripe\Forms\GridField\GridFieldFilterHeader or ilateral\SilverStripe\Mo...nPlus\ModelAdminSnippet or Symbiote\GridFieldExtens...\GridFieldOrderableRows or SilverStripe\Forms\GridField\GridFieldFilterHeader or Symbiote\GridFieldExtens...\GridFieldOrderableRows or SilverStripe\Forms\GridField\GridFieldPrintButton or Symbiote\GridFieldExtens...\GridFieldOrderableRows or SilverStripe\Forms\GridField\GridFieldFilterHeader or SilverStripe\Forms\Tests...ndlerTest\TestComponent or SilverStripe\Forms\GridField\GridFieldDetailForm or Symbiote\GridFieldExtens...\GridFieldOrderableRows .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
294 | |||||
295 | /** @var AutoCompleteField */ |
||||
296 | $field = isset($form) ? $form->Fields()->fieldByName($name) : null; |
||||
297 | |||||
298 | if (isset($field)) { |
||||
299 | return $field->Suggest($request); |
||||
300 | } |
||||
301 | |||||
302 | // the response body |
||||
303 | return json_encode([]); |
||||
304 | } |
||||
305 | } |
||||
306 |