Passed
Push — 1 ( f90126...643c16 )
by Morven
04:19
created

ModelAdminPlus::getSnippets()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 0
dl 0
loc 16
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace ilateral\SilverStripe\ModelAdminPlus;
4
5
use SilverStripe\ORM\ArrayLib;
6
use SilverStripe\ORM\ArrayList;
7
use SilverStripe\Core\ClassInfo;
8
use SilverStripe\Admin\ModelAdmin;
9
use SilverStripe\View\Requirements;
10
use Colymba\BulkManager\BulkManager;
11
use SilverStripe\Control\Controller;
12
use SilverStripe\Core\Config\Config;
13
use SilverStripe\Forms\DatetimeField;
14
use SilverStripe\Core\Injector\Injector;
15
use Colymba\BulkManager\BulkAction\UnlinkHandler;
16
use SilverStripe\Forms\GridField\GridFieldPaginator;
17
use SilverStripe\Forms\GridField\GridFieldDataColumns;
18
use SilverStripe\Forms\GridField\GridFieldSortableHeader;
19
use SilverStripe\Forms\GridField\GridField_ColumnProvider;
20
use Symbiote\GridFieldExtensions\GridFieldConfigurablePaginator;
21
22
/**
23
 * Custom version of model admin that adds extra features
24
 * (such as submitting search results via a POST, saving the query
25
 * as a session and automatic Bulk Editing support)
26
 *
27
 * @author ilateral
28
 * @package ModelAdminPlus
29
 */
30
abstract class ModelAdminPlus extends ModelAdmin
31
{
32
    const EXPORT_FIELDS = "export_fields";
33
34
    /**
35
     * Automatically convert date fields on gridfields
36
     * to use `Date.Nice`.
37
     * 
38
     * @var boolean
39
     */
40
    private static $auto_convert_dates = true;
41
42
    private static $allowed_actions = [
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
43
        "SearchForm"
44
    ];
45
46
    /**
47
     * List of currently registered ModelAdminSnippets, that is represented as
48
     * a list of classnames.
49
     *
50
     * These snippets are then setup when ModelAdminPlus is initilised and
51
     * rendered into the ModelAdminPlus content template.
52
     *
53
     * @var array
54
     */
55
    private static $registered_snippets = [];
56
57
    /**
58
     * Setup 
59
     */
60
    public function getSnippets()
61
    {
62
        $snippets = ArrayList::create();
63
64
        // Setup any model admin plus snippets
65
        foreach ($this->config()->registered_snippets as $snippet) {
66
            $snippet = Injector::inst()->create($snippet);
67
            $snippet->setParent($this);
68
            $snippets->add($snippet);
69
        }
70
71
        $snippets = $snippets->sort("Order", "DESC");
72
73
        $this->extend("updateSnippets", $snippets);
74
75
        return $snippets;
76
    }
77
78
    public function init()
79
    {
80
        parent::init();
81
82
        // Require additional CSS
83
        Requirements::css("i-lateral/silverstripe-modeladminplus:client/dist/css/admin.css");
84
85
        $clear = $this->getRequest()->getVar("clear");
86
87
        if (isset($clear) && $clear == 1) {
88
            $this->clearSearchSession();
89
            // Remove clear flag
90
            return $this->redirect(
91
                $this->Link(
92
                    $this->sanitiseClassName($this->modelClass)
93
                )
94
            );
95
        }
96
    }
97
98
    /**
99
     * Get the default export fields for the current model.
100
     *
101
     * First this checks if there is an `export_fields` config variable set on
102
     * the model class, if not, it reverts to the default behaviour.
103
     *
104
     * @return array
105
     */
106
    public function getExportFields()
107
    {
108
        $export_fields = Config::inst()->get(
109
            $this->modelClass,
110
            self::EXPORT_FIELDS
111
        );
112
113
        if (isset($export_fields) && is_array($export_fields)) {
114
            $fields = $export_fields;
115
        } else {
116
            $fields = parent::getExportFields();
117
        }
118
119
        $this->extend("updateExportFields", $fields);
120
121
        return $fields;
122
    }
123
124
    /**
125
     * Get the name of the session to be useed by this model admin's search
126
     * form.
127
     *
128
     * @return string
129
     */
130
    public function getSearchSessionName()
131
    {
132
        $curr = $this->sanitiseClassName(self::class);
133
        $model = $this->sanitiseClassName($this->modelClass);
134
        return $curr . "." . $model;
135
    }
136
137
    /**
138
     * Empty the current search session
139
     *
140
     * @return Session
0 ignored issues
show
Bug introduced by
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. 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...
141
     */
142
    public function clearSearchSession()
143
    {
144
        $session = $this->getRequest()->getSession();
145
        return $session->clear($this->getSearchSessionName());
146
    }
147
148
    /**
149
     * Get the current search session
150
     *
151
     * @return Session
152
     */
153
    public function getSearchSession()
154
    {
155
        $session = $this->getRequest()->getSession();
156
        return $session->get($this->getSearchSessionName());
157
    }
158
159
    /**
160
     * Set some data to a search session. This needs to be an array of
161
     * data (like the data submitted by a form).
162
     *
163
     * @param array $data An array of data to store in the session
164
     *
165
     * @return self
166
     */
167
    public function setSearchSession($data)
168
    {
169
        $session = $this->getRequest()->getSession();
170
        return $session->set($this->getSearchSessionName(), $data);
171
    }
172
173
    /**
174
     * Get the current search results, combined with any saved
175
     * search results and resturn (as an array).
176
     *
177
     * @return array
178
     */
179
    public function getSearchData()
180
    {
181
        $data = $this->getSearchSession();
182
183
        if (!$data || $data && !is_array($data)) {
0 ignored issues
show
introduced by
$data is of type ilateral\SilverStripe\ModelAdminPlus\Session, thus it always evaluated to true.
Loading history...
introduced by
The condition is_array($data) is always false.
Loading history...
184
            $data = [];
185
        }
186
187
        return $data;
188
    }
189
190
    /**
191
     * Overwrite the default search list to account for the new session based
192
     * search data.
193
     *
194
     * You can override how ModelAdmin returns DataObjects by either overloading this method,
195
     * or defining an extension to ModelAdmin that implements the `updateList` method
196
     * (and takes a {@link \SilverStripe\ORM\DataList} as the
197
     * first argument).
198
     *
199
     * @return \SilverStripe\ORM\DataList
200
     */
201
    public function getList()
202
    {
203
        $context = $this->getSearchContext();
0 ignored issues
show
Deprecated Code introduced by
The function SilverStripe\Admin\ModelAdmin::getSearchContext() has been deprecated: 5.0 ( Ignorable by Annotation )

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

203
        $context = /** @scrutinizer ignore-deprecated */ $this->getSearchContext();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
204
        $params = $this->getSearchData();
205
206
        if (is_array($params)) {
0 ignored issues
show
introduced by
The condition is_array($params) is always true.
Loading history...
207
            $params = ArrayLib::array_map_recursive('trim', $params);
208
209
            // Parse all DateFields to handle user input non ISO 8601 dates
210
            foreach ($context->getFields() as $field) {
211
                if ($field instanceof DatetimeField && !empty($params[$field->getName()])) {
212
                    $params[$field->getName()] = date(
213
                        'Y-m-d',
214
                        strtotime($params[$field->getName()])
215
                    );
216
                }
217
            }
218
        }
219
220
        $list = $context->getResults($params);
221
222
        $this->extend('updateList', $list);
223
224
        return $list;
225
    }
226
227
    /**
228
     * Gets a list of fields that have been searched
229
     *
230
     * @return SilverStripe\ORM\ArrayList
0 ignored issues
show
Bug introduced by
The type ilateral\SilverStripe\Mo...verStripe\ORM\ArrayList was not found. Did you mean SilverStripe\ORM\ArrayList? If so, make sure to prefix the type with \.
Loading history...
231
     */
232
    public function SearchSummary()
233
    {
234
        $context = $this->getSearchContext();
0 ignored issues
show
Deprecated Code introduced by
The function SilverStripe\Admin\ModelAdmin::getSearchContext() has been deprecated: 5.0 ( Ignorable by Annotation )

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

234
        $context = /** @scrutinizer ignore-deprecated */ $this->getSearchContext();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
235
        $params = $this->getSearchData();
236
        $context->setSearchParams($params);
237
238
        return $context->getSummary();
239
    }
240
241
    
242
    /**
243
     * Add bulk editor to Edit Form
244
     *
245
     * @param int|null  $id
246
     * @param FieldList $fields
0 ignored issues
show
Bug introduced by
The type ilateral\SilverStripe\ModelAdminPlus\FieldList 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...
247
     *
248
     * @return Form A Form object
0 ignored issues
show
Bug introduced by
The type ilateral\SilverStripe\ModelAdminPlus\Form 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...
249
     */
250
    public function getEditForm($id = null, $fields = null)
251
    {
252
        $form = parent::getEditForm($id, $fields);
253
        $grid_field = $form
254
            ->Fields()
255
            ->fieldByName($this->sanitiseClassName($this->modelClass));
256
257
        // Add bulk editing to gridfield
258
        $manager = new BulkManager();
259
        $manager->removeBulkAction(UnlinkHandler::class);
260
261
        $config = $grid_field->getConfig();
262
263
        $config
264
            ->removeComponentsByType(GridFieldPaginator::class)
265
            ->addComponent($manager)
266
            ->addComponent(new GridFieldConfigurablePaginator());
267
268
        if ($this->config()->auto_convert_dates) {
269
            GridFieldDateFinder::create($grid_field)->convertDateFields();
270
        }
271
272
        return $form;
273
    }
274
275
    /**
276
     * Overwrite default search form
277
     * 
278
     * @return Form
279
     */
280
    public function SearchForm()
281
    {
282
        $form = parent::SearchForm();
0 ignored issues
show
Deprecated Code introduced by
The function SilverStripe\Admin\ModelAdmin::SearchForm() has been deprecated: 5.0 ( Ignorable by Annotation )

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

282
        $form = /** @scrutinizer ignore-deprecated */ parent::SearchForm();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
283
        $fields = $form->Fields();
284
        $data = $this->getSearchData();
285
286
        // Change currently scaffolded query fields to use conventional
287
        // field names
288
        foreach ($fields as $field) {
289
            $name = $field->getName();
290
291
            if ($name[0] == "q" && $name[1] == "[") {
292
                $name = substr($name, 2);
293
            }
294
295
            if (substr($name, -1) == "]") {
296
                $name = substr($name, 0, -1);
297
            }
298
299
            $field->setName($name);
300
        }
301
302
        $form
303
            ->removeExtraClass('cms-search-form')
304
            ->setFormMethod('post')
305
            ->setFormAction(
306
                $this->Link(
307
                    Controller::join_links(
308
                        $this->sanitiseClassName($this->modelClass),
309
                        $form->getName()
310
                    )
311
                )
312
            )->loadDataFrom($data);
313
314
        return $form;
315
    }
316
317
    /**
318
     * Set the session from the submitted form data (and redirect back)
319
     *
320
     * @param array $data Submitted form
321
     * @param Form  $form The current form
322
     *
323
     * @return HTTPResponse
0 ignored issues
show
Bug introduced by
The type ilateral\SilverStripe\ModelAdminPlus\HTTPResponse was not found. Did you mean HTTPResponse? If so, make sure to prefix the type with \.
Loading history...
324
     */
325
    public function search($data, $form)
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed. ( Ignorable by Annotation )

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

325
    public function search($data, /** @scrutinizer ignore-unused */ $form)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
326
    {
327
        foreach ($data as $key => $value) {
328
            // Ensure we clear any null values
329
            // so they don't mess up the list
330
            if (empty($data[$key])) {
331
                unset($data[$key]);
332
            }
333
334
            // Ensure we clear any null values
335
            // so they don't mess up the list
336
            if (strpos($key, "action_") !== false) {
337
                unset($data[$key]);
338
            }
339
        }
340
341
        $this->setSearchSession($data);
342
343
        return $this->redirectBack();
344
    }
345
}
346