GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 21e795...aea957 )
by
unknown
11s
created

code/admin/AdvancedWorkflowAdmin.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 Symbiote\AdvancedWorkflow\Admin;
4
5
use SilverStripe\Admin\ModelAdmin;
6
use SilverStripe\CMS\Controllers\CMSPageEditController;
7
use SilverStripe\Control\HTTPRequest;
8
use SilverStripe\Core\Manifest\ModuleLoader;
9
use SilverStripe\Forms\GridField\GridField;
10
use SilverStripe\Forms\GridField\GridFieldConfig_Base;
11
use SilverStripe\Forms\GridField\GridFieldDataColumns;
12
use SilverStripe\Forms\GridField\GridFieldEditButton;
13
use SilverStripe\Forms\GridField\GridFieldDetailForm;
14
use SilverStripe\Forms\GridField\GridFieldPaginator;
15
use SilverStripe\Forms\FieldList;
16
use SilverStripe\Forms\FormAction;
17
use SilverStripe\Forms\GridField\GridFieldExportButton;
18
use SilverStripe\ORM\ArrayList;
19
use SilverStripe\ORM\DataObject;
20
use SilverStripe\Security\Member;
21
use SilverStripe\Security\Permission;
22
use SilverStripe\View\Requirements;
23
use Symbiote\AdvancedWorkflow\Admin\WorkflowDefinitionItemRequestClass;
24
use Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition;
25
use Symbiote\AdvancedWorkflow\Dev\WorkflowBulkLoader;
26
use Symbiote\AdvancedWorkflow\Forms\GridField\GridFieldExportAction;
27
use Symbiote\AdvancedWorkflow\Forms\GridField\GridFieldWorkflowRestrictedEditButton;
28
use Symbiote\AdvancedWorkflow\Services\WorkflowService;
29
30
/**
31
 * @package advancedworkflow
32
 * @todo UI/UX needs looking at for when current user has no pending and/or submitted items, (Current implementation is bog-standard <p> text)
33
 */
34
class AdvancedWorkflowAdmin extends ModelAdmin
35
{
36
    private static $menu_title    = 'Workflows';
37
    private static $menu_priority = -1;
38
    private static $url_segment   = 'workflows';
39
    private static $menu_icon = "advancedworkflow/images/workflow-menu-icon.png";
0 ignored issues
show
The property $menu_icon is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
40
41
    /**
42
     *
43
     * @var array Allowable actions on this controller.
44
     */
45
    private static $allowed_actions = array(
46
        'export',
47
        'ImportForm'
48
    );
49
50
    private static $url_handlers = array(
51
        '$ModelClass/export/$ID!' => 'export',
52
        '$ModelClass/$Action' => 'handleAction',
53
        '' => 'index'
54
    );
55
56
    private static $managed_models = WorkflowDefinition::class;
57
58
    private static $model_importers = array(
59
        'WorkflowDefinition' => WorkflowBulkLoader::class
60
    );
61
62
    private static $dependencies = array(
63
        'workflowService' => '%$' . WorkflowService::class,
64
    );
65
66
    private static $fileEditActions = 'getCMSActions';
67
68
    /**
69
     * Defaults are set in {@link getEditForm()}.
70
     *
71
     * @var array
72
     */
73
    private static $fieldOverrides = array();
74
75
    /**
76
     * @var WorkflowService
77
     */
78
    public $workflowService;
79
80
    /**
81
     * Initialise javascript translation files
82
     *
83
     * @return void
84
     */
85
    protected function init()
86
    {
87
        parent::init();
88
89
        Requirements::add_i18n_javascript('symbiote/silverstripe-advancedworkflow:client/lang');
90
        Requirements::javascript('symbiote/silverstripe-advancedworkflow:client/dist/js/advancedworkflow.js');
91
        Requirements::css('symbiote/silverstripe-advancedworkflow:client/dist/styles/advancedworkflow.css');
92
    }
93
94
    /*
95
	 * Shows up to x2 GridFields for Pending and Submitted items, dependent upon the current CMS user and that user's permissions
96
	 * on the objects showing in each field.
97
	 */
98
    public function getEditForm($id = null, $fields = null)
99
    {
100
        $form = parent::getEditForm($id, $fields);
101
102
        // Show items submitted into a workflow for current user to action
103
        $fieldName = 'PendingObjects';
104
        $pending = $this->userObjects(Member::currentUser(), $fieldName);
105
106
        if ($this->config()->fieldOverrides) {
107
            $displayFields = $this->config()->fieldOverrides;
108
        } else {
109
            $displayFields = array(
110
                'Title'          => _t('AdvancedWorkflowAdmin.Title', 'Title'),
111
                'LastEdited'     => _t('AdvancedWorkflowAdmin.LastEdited', 'Changed'),
112
                'WorkflowTitle'  => _t('AdvancedWorkflowAdmin.WorkflowTitle', 'Effective workflow'),
113
                'WorkflowStatus' => _t('AdvancedWorkflowAdmin.WorkflowStatus', 'Current action'),
114
            );
115
        }
116
117
        // Pending/Submitted items GridField Config
118
        $config = new GridFieldConfig_Base();
119
        $config->addComponent(new GridFieldEditButton());
120
        $config->addComponent(new GridFieldDetailForm());
121
        $config->getComponentByType(GridFieldPaginator::class)->setItemsPerPage(5);
122
        $columns = $config->getComponentByType(GridFieldDataColumns::class);
123
        $columns->setFieldFormatting($this->setFieldFormatting($config));
124
125
        if ($pending->count()) {
126
            $formFieldTop = GridField::create(
127
                $fieldName,
128
                $this->isAdminUser(Member::currentUser())?
129
                    _t(
130
                        'AdvancedWorkflowAdmin.GridFieldTitleAssignedAll',
131
                        'All pending items'
132
                    ):
133
                    _t(
134
                        'AdvancedWorkflowAdmin.GridFieldTitleAssignedYour',
135
                        'Your pending items'
136
                    ),
137
                $pending,
138
                $config
139
            );
140
141
            $dataColumns = $formFieldTop->getConfig()->getComponentByType(GridFieldDataColumns::class);
142
            $dataColumns->setDisplayFields($displayFields);
143
144
            $formFieldTop->setForm($form);
145
            $form->Fields()->insertBefore($formFieldTop, WorkflowDefinition::class);
146
        }
147
148
        // Show items submitted into a workflow by current user
149
        $fieldName = 'SubmittedObjects';
150
        $submitted = $this->userObjects(Member::currentUser(), $fieldName);
151
        if ($submitted->count()) {
152
            $formFieldBottom = GridField::create(
153
                $fieldName,
154
                $this->isAdminUser(Member::currentUser())?
155
                    _t(
156
                        'AdvancedWorkflowAdmin.GridFieldTitleSubmittedAll',
157
                        'All submitted items'
158
                    ):
159
                    _t(
160
                        'AdvancedWorkflowAdmin.GridFieldTitleSubmittedYour',
161
                        'Your submitted items'
162
                    ),
163
                $submitted,
164
                $config
165
            );
166
167
            $dataColumns = $formFieldBottom->getConfig()->getComponentByType(GridFieldDataColumns::class);
168
            $dataColumns->setDisplayFields($displayFields);
169
170
            $formFieldBottom->setForm($form);
171
            $formFieldBottom->getConfig()->removeComponentsByType(GridFieldEditButton::class);
172
            $formFieldBottom->getConfig()->addComponent(new GridFieldWorkflowRestrictedEditButton());
173
            $form->Fields()->insertBefore($formFieldBottom, WorkflowDefinition::class);
174
        }
175
176
        $grid = $form->Fields()->dataFieldByName(WorkflowDefinition::class);
177
        if ($grid) {
178
            $grid->getConfig()->getComponentByType(GridFieldDetailForm::class)->setItemEditFormCallback(function ($form) {
179
                $record = $form->getRecord();
180
                if ($record) {
181
                    $record->updateAdminActions($form->Actions());
182
                }
183
            });
184
185
            $grid->getConfig()->getComponentByType(GridFieldDetailForm::class)->setItemRequestClass(WorkflowDefinitionItemRequestClass::class);
186
            $grid->getConfig()->addComponent(new GridFieldExportAction());
187
            $grid->getConfig()->removeComponentsByType(GridFieldExportButton::class);
188
        }
189
190
        return $form;
191
    }
192
193
    /*
194
	 * @param Member $user
195
	 * @return boolean
196
	 */
197
    public function isAdminUser(Member $user)
198
    {
199
        if (Permission::checkMember($user, 'ADMIN')) {
200
            return true;
201
        }
202
        return false;
203
    }
204
205
    /*
206
	 * By default, we implement GridField_ColumnProvider to allow users to click through to the PagesAdmin.
207
	 * We would also like a "Quick View", that allows users to quickly make a decision on a given workflow-bound content-object
208
	 */
209
    public function columns()
210
    {
211
        $fields = array(
212
            'Title' => array(
213
                'link' => function ($value, $item) {
214
                    $pageAdminLink = singleton(CMSPageEditController::class)->Link('show');
215
                    return sprintf('<a href="%s/%s">%s</a>', $pageAdminLink, $item->Link, $value);
216
                }
217
            ),
218
            'WorkflowStatus' => array(
219
                'text' => function ($value, $item) {
220
                    return $item->WorkflowCurrentAction;
221
                }
222
            )
223
        );
224
        return $fields;
225
    }
226
227
    /*
228
	 * Discreet method used by both intro gridfields to format the target object's links and clickable text
229
	 *
230
	 * @param GridFieldConfig $config
231
	 * @return array $fieldFormatting
232
	 */
233
    public function setFieldFormatting(&$config)
234
    {
235
        $fieldFormatting = array();
236
        // Parse the column information
237
        foreach ($this->columns() as $source => $info) {
238
            if (isset($info['link']) && $info['link']) {
239
                $fieldFormatting[$source] = '<a href=\"$ObjectRecordLink\">$value</a>';
240
            }
241
            if (isset($info['text']) && $info['text']) {
242
                $fieldFormatting[$source] = $info['text'];
243
            }
244
        }
245
        return $fieldFormatting;
246
    }
247
248
    /**
249
     * Get WorkflowInstance Target objects to show for users in initial gridfield(s)
250
     *
251
     * @param Member $member
252
     * @param string $fieldName The name of the gridfield that determines which dataset to return
253
     * @return DataList
254
     * @todo Add the ability to see embargo/expiry dates in report-gridfields at-a-glance if QueuedJobs module installed
255
     */
256
    public function userObjects(Member $user, $fieldName)
257
    {
258
        $list = new ArrayList();
259
        $userWorkflowInstances = $this->getFieldDependentData($user, $fieldName);
260
        foreach ($userWorkflowInstances as $instance) {
261
            if (!$instance->TargetID || !$instance->DefinitionID) {
262
                continue;
263
            }
264
            // @todo can we use $this->getDefinitionFor() to fetch the "Parent" definition of $instance? Maybe define $this->workflowParent()
265
            $effectiveWorkflow = DataObject::get_by_id(WorkflowDefinition::class, $instance->DefinitionID);
266
            $target = $instance->getTarget();
267
            if (!is_object($effectiveWorkflow) || !$target) {
268
                continue;
269
            }
270
            $instance->setField('WorkflowTitle', $effectiveWorkflow->getField('Title'));
271
            $instance->setField('WorkflowCurrentAction', $instance->getCurrentAction());
272
            // Note the order of property-setting here, somehow $instance->Title is overwritten by the Target Title property..
273
            $instance->setField('Title', $target->getField('Title'));
274
            $instance->setField('LastEdited', $target->getField('LastEdited'));
275
            if (method_exists($target, 'CMSEditLink')) {
276
                $instance->setField('ObjectRecordLink', $target->CMSEditLink());
277
            }
278
279
            $list->push($instance);
280
        }
281
        return $list;
282
    }
283
284
    /*
285
	 * Return content-object data depending on which gridfeld is calling for it
286
	 *
287
	 * @param Member $user
288
	 * @param string $fieldName
289
	 */
290
    public function getFieldDependentData(Member $user, $fieldName)
291
    {
292
        if ($fieldName == 'PendingObjects') {
293
            return $this->workflowService->userPendingItems($user);
294
        }
295
        if ($fieldName == 'SubmittedObjects') {
296
            return $this->workflowService->userSubmittedItems($user);
297
        }
298
    }
299
300
    /**
301
     * Spits out an exported version of the selected WorkflowDefinition for download.
302
     *
303
     * @param HTTPRequest $request
304
     * @return HTTPResponse
305
     */
306
    public function export(HTTPRequest $request)
307
    {
308
        $url = explode('/', $request->getURL());
309
        $definitionID = end($url);
310
        if ($definitionID && is_numeric($definitionID)) {
311
            $exporter = new WorkflowDefinitionExporter($definitionID);
312
            $exportFilename = WorkflowDefinitionExporter::$export_filename_prefix.'-'.$definitionID.'.yml';
313
            $exportBody = $exporter->export();
314
            $fileData = array(
315
                'name' => $exportFilename,
316
                'mime' => 'text/x-yaml',
317
                'body' => $exportBody,
318
                'size' => $exporter->getExportSize($exportBody)
319
            );
320
            return $exporter->sendFile($fileData);
321
        }
322
    }
323
324
    /**
325
     * Required so we can simply change the visible label of the "Import" button and lose some redundant form-fields.
326
     *
327
     * @return Form
328
     */
329
    public function ImportForm()
330
    {
331
        $form = parent::ImportForm();
332
        if (!$form) {
333
            return;
334
        }
335
336
        $form->unsetAllActions();
337
        $newActionList = new FieldList(array(
338
            new FormAction('import', _t('AdvancedWorkflowAdmin.IMPORT', 'Import workflow'))
339
        ));
340
        $form->Fields()->fieldByName('_CsvFile')->getValidator()->setAllowedExtensions(array('yml', 'yaml'));
341
        $form->Fields()->removeByName('EmptyBeforeImport');
342
        $form->setActions($newActionList);
343
344
        return $form;
345
    }
346
}
347