Completed
Push — master ( b8da20...856b73 )
by
unknown
02:45
created

code/Forms/AssetFormFactory.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace SilverStripe\AssetAdmin\Forms;
4
5
use InvalidArgumentException;
6
use SilverStripe\Assets\File;
7
use SilverStripe\Control\RequestHandler;
8
use SilverStripe\Assets\Folder;
9
use SilverStripe\Core\Config\Configurable;
10
use SilverStripe\Core\Extensible;
11
use SilverStripe\Core\Injector\Injectable;
12
use SilverStripe\Forms\CheckboxSetField;
13
use SilverStripe\Forms\FieldList;
14
use SilverStripe\Forms\Form;
15
use SilverStripe\Forms\FormAction;
16
use SilverStripe\Forms\FormFactory;
17
use SilverStripe\Forms\HeaderField;
18
use SilverStripe\Forms\HiddenField;
19
use SilverStripe\Forms\OptionsetField;
20
use SilverStripe\Forms\PopoverField;
21
use SilverStripe\Forms\ReadonlyField;
22
use SilverStripe\Forms\RequiredFields;
23
use SilverStripe\Forms\Tab;
24
use SilverStripe\Forms\TabSet;
25
use SilverStripe\Forms\TextField;
26
use SilverStripe\Security\Group;
27
use SilverStripe\Forms\TreeDropdownField;
28
29
abstract class AssetFormFactory implements FormFactory
30
{
31
    use Extensible;
32
    use Injectable;
33
    use Configurable;
34
35
    /**
36
     * Insert into HTML content area as a media object
37
     */
38
    const TYPE_INSERT_MEDIA = 'insert-media';
39
    
40
    /**
41
     * Insert into HTML content area as a link
42
     */
43
    const TYPE_INSERT_LINK = 'insert-link';
44
    
45
    /**
46
     * Select file by ID only
47
     */
48
    const TYPE_SELECT = 'select';
49
50
    /**
51
     * Edit form: Default
52
     */
53
    const TYPE_ADMIN = 'admin';
54
55
    public function __construct()
56
    {
57
        $this->constructExtensions();
58
    }
59
60
    /**
61
     * @param RequestHandler $controller
62
     * @param string $name
63
     * @param array $context
64
     * @return Form
65
     */
66
    public function getForm(RequestHandler $controller = null, $name = FormFactory::DEFAULT_NAME, $context = [])
67
    {
68
        // Validate context
69
        foreach ($this->getRequiredContext() as $required) {
70
            if (!isset($context[$required])) {
71
                throw new InvalidArgumentException("Missing required context $required");
72
            }
73
        }
74
75
        $fields = $this->getFormFields($controller, $name, $context);
76
        $actions = $this->getFormActions($controller, $name, $context);
77
        $validator = $this->getValidator($controller, $name, $context);
78
        $form = Form::create($controller, $name, $fields, $actions, $validator);
79
80
        // Extend form
81
        $this->invokeWithExtensions('updateForm', $form, $controller, $name, $context);
82
83
        // Populate form from record
84
        if (isset($context['Record'])) {
85
            /** @var File $record */
86
            $record = $context['Record'];
87
            $form->loadDataFrom($record);
88
89
            if (!$record->canEdit()) {
90
                $form->makeReadonly();
91
            }
92
        }
93
94
        $form->addExtraClass('form--fill-height form--padded');
95
96
        return $form;
97
    }
98
99
    /**
100
     * Get the validator for the form to be built
101
     *
102
     * @param RequestHandler $controller
103
     * @param $formName
104
     * @param $context
105
     * @return RequiredFields
106
     */
107
    protected function getValidator(RequestHandler $controller = null, $formName, $context = [])
108
    {
109
        $validator = new RequiredFields('Name');
110
111
        return $validator;
112
    }
113
114
    /**
115
     * Get form type from 'type' context
116
     *
117
     * @param array $context
118
     * @return string
119
     */
120
    protected function getFormType($context)
121
    {
122
        return empty($context['Type']) ? static::TYPE_ADMIN : $context['Type'];
123
    }
124
125
    /**
126
     * Gets the main tabs for the file edit form
127
     *
128
     * @param File $record
129
     * @param array $context
130
     * @return TabSet
131
     */
132
    protected function getFormFieldTabs($record, $context = [])
133
    {
134
        return TabSet::create(
135
            'Editor',
136
            [
137
                $this->getFormFieldDetailsTab($record, $context),
138
                $this->getFormFieldSecurityTab($record, $context),
139
            ]
140
        );
141
    }
142
143
    /**
144
     * @param File $record
145
     * @return FormAction
146
     */
147 View Code Duplication
    protected function getSaveAction($record)
148
    {
149
        if ($record && $record->isInDB() && $record->canEdit()) {
150
            return FormAction::create('save', _t('SilverStripe\\CMS\\Controllers\\CMSMain.SAVE', 'Save'))
151
                ->setIcon('save');
152
        }
153
        return null;
154
    }
155
156
    /**
157
     * Get delete action, if this record is deletable
158
     *
159
     * @param File $record
160
     * @return FormAction
161
     */
162 View Code Duplication
    protected function getDeleteAction($record)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
163
    {
164
        // Delete action
165
        if ($record && $record->isInDB() && $record->canDelete()) {
166
            $deleteText = _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.DELETE_BUTTON', 'Delete');
167
            return FormAction::create('delete', $deleteText)
168
                ->setIcon('trash-bin');
169
        }
170
        return null;
171
    }
172
173
    /**
174
     * @param RequestHandler $controller
175
     * @param $formName
176
     * @param array $context
177
     * @return FieldList
178
     */
179
    protected function getFormActions(RequestHandler $controller = null, $formName, $context = [])
180
    {
181
        $record = isset($context['Record']) ? $context['Record'] : null;
182
183
        $actions = new FieldList();
184
        if ($saveAction = $this->getSaveAction($record)) {
185
            $actions->push($saveAction);
186
        }
187
        $menu = $this->getPopoverMenu($record);
188
        if ($menu && $menu->FieldList()->count()) {
189
            $actions->push($menu);
190
        }
191
192
        $this->invokeWithExtensions('updateFormActions', $actions, $controller, $formName, $context);
193
        return $actions;
194
    }
195
196
    /**
197
     * Get fields for this form
198
     *
199
     * @param RequestHandler $controller
200
     * @param string $formName
201
     * @param array $context
202
     * @return FieldList
203
     */
204
    protected function getFormFields(RequestHandler $controller = null, $formName, $context = [])
205
    {
206
        $record = isset($context['Record']) ? $context['Record'] : null;
207
208
        // Build standard fields for all folders / files
209
        /** @var File $record */
210
        $fields = new FieldList(
211
            HeaderField::create('TitleHeader', $record ? $record->Title : null, 1)
212
                ->addExtraClass('editor__heading'),
213
            $this->getFormFieldTabs($record, $context)
214
        );
215
        if ($record) {
216
            $fields->push(HiddenField::create('ID', $record->ID));
217
            $fields->insertAfter(
218
                'TitleHeader',
219
                PreviewImageField::create('PreviewImage')
220
                    ->setRecordID($record->ID)
221
                    ->addExtraClass('editor__file-preview')
222
            );
223
        }
224
225
        $this->invokeWithExtensions('updateFormFields', $fields, $controller, $formName, $context);
226
        return $fields;
227
    }
228
229
    /**
230
     * Build popup menu
231
     *
232
     * @param File $record
233
     * @return PopoverField
234
     */
235
    protected function getPopoverMenu($record)
236
    {
237
        // Build popover actions
238
        $popoverActions = $this->getPopoverActions($record);
239
        if ($popoverActions) {
240
            return PopoverField::create($popoverActions)
241
                ->setPlacement('top')
242
                ->setName('PopoverActions')
243
                ->setButtonTooltip(_t(
244
                    'SilverStripe\\AssetAdmin\\Forms\\FileFormFactory.OTHER_ACTIONS',
245
                    'Other actions'
246
                ));
247
        }
248
        return null;
249
    }
250
251
    /**
252
     * Get actions that go into the Popover menu
253
     *
254
     * @param File $record
255
     * @return array
256
     */
257
    protected function getPopoverActions($record)
258
    {
259
        $actions = [
260
            $this->getDeleteAction($record)
261
        ];
262
263
        $this->invokeWithExtensions('updatePopoverActions', $actions, $record);
264
        return array_filter($actions);
265
    }
266
267
    /**
268
     * Build "details" formfield tab
269
     *
270
     * @param File $record
271
     * @param array $context
272
     * @return Tab
273
     */
274
    protected function getFormFieldDetailsTab($record, $context = [])
275
    {
276
        /** @var Tab $tab */
277
        $tab = Tab::create(
278
            'Details',
279
            TextField::create('Name', File::singleton()->fieldLabel('Filename')),
280
            $location = TreeDropdownField::create('ParentID', 'FolderLocation', Folder::class),
281
            ReadonlyField::create(
282
                "Path",
283
                _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.PATH', 'Path'),
284
                $this->getPath($record, $context)
285
            )
286
        );
287
        
288
        $location->setEmptyString('(root)');
289
        return $tab;
290
    }
291
    
292
    /**
293
     * Get user-visible "Path" for this record
294
     *
295
     * @param File $record
296
     * @param array $context
297
     * @return string
298
     */
299
    protected function getPath($record, $context = [])
300
    {
301
        if ($record && $record->isInDB()) {
302
            if ($record->ParentID) {
303
                return $record->Parent()->getFilename();
304
            } else {
305
                return '/';
306
            }
307
        }
308
        if (isset($context['ParentID'])) {
309
            if ($context['ParentID'] === 0) {
310
                return '/';
311
            }
312
            $file = File::get()->byID($context['ParentID']);
313
            if ($file) {
314
                return $file->getFilename();
315
            }
316
        }
317
        return null;
318
    }
319
320
    /**
321
     * Build security tab
322
     *
323
     * @param File $record
324
     * @param array $context
325
     * @return Tab
326
     */
327
    protected function getFormFieldSecurityTab($record, $context = [])
328
    {
329
        // Get groups
330
        $groupsMap = array();
331
        foreach (Group::get() as $group) {
332
            $groupsMap[$group->ID] = $group->getBreadcrumbs(' > ');
333
        }
334
        asort($groupsMap);
335
336
        // Get permissions
337
        $viewersOptionsField = [
338
            'Inherit' => _t(__CLASS__.'.INHERIT', 'Inherit from parent folder'),
339
            'Anyone' => _t(__CLASS__.'.ANYONE', 'Anyone'),
340
            'LoggedInUsers' => _t(__CLASS__.'.LOGGED_IN', 'Logged-in users'),
341
            'OnlyTheseUsers' => _t(__CLASS__.'.ONLY_GROUPS', 'Only these people (choose from list)')
342
        ];
343
344
        // No "Anyone" editors option
345
        $editorsOptionsField = $viewersOptionsField;
346
        unset($editorsOptionsField['Anyone']);
347
348
        return Tab::create(
349
            'Permissions',
350
            OptionsetField::create(
351
                'CanViewType',
352
                _t(__CLASS__.'.ACCESSHEADER', 'Who can view this file?')
353
            )
354
                ->setSource($viewersOptionsField),
355
            CheckboxSetField::create('ViewerGroups', _t(__CLASS__.'.VIEWERGROUPS', 'Viewer Groups'))
356
                ->setSource($groupsMap),
357
            OptionsetField::create(
358
                "CanEditType",
359
                _t(__CLASS__.'.EDITHEADER', 'Who can edit this file?')
360
            )
361
                ->setSource($editorsOptionsField),
362
            CheckboxSetField::create('EditorGroups', _t(__CLASS__.'.EDITORGROUPS', 'Editor Groups'))
363
                ->setSource($groupsMap)
364
        );
365
    }
366
367
    public function getRequiredContext()
368
    {
369
        return ['Record'];
370
    }
371
}
372