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 ( 12253c...6b2d71 )
by Robbie
26:46 queued 20:26
created

AdvancedWorkflowExtension::updateEditForm()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 41
rs 8.6417
c 0
b 0
f 0
cc 6
nc 7
nop 1
1
<?php
2
3
namespace Symbiote\AdvancedWorkflow\Extensions;
4
5
use SilverStripe\Control\Controller;
6
use SilverStripe\Control\HTTPRequest;
7
use SilverStripe\Core\Extension;
8
use SilverStripe\Core\Manifest\ModuleLoader;
9
use SilverStripe\Forms\Form;
10
use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest;
11
use SilverStripe\ORM\DataObject;
12
use SilverStripe\Security\Permission;
13
use SilverStripe\View\Requirements;
14
use Symbiote\AdvancedWorkflow\Extensions\WorkflowApplicable;
15
use Symbiote\AdvancedWorkflow\Services\WorkflowService;
16
17
/**
18
 * Handles interactions triggered by users in the backend of the CMS. Replicate this
19
 * type of functionality wherever you need UI interaction with workflow.
20
 *
21
 * @author  [email protected]
22
 * @license BSD License (http://silverstripe.org/bsd-license/)
23
 * @package advancedworkflow
24
 */
25
class AdvancedWorkflowExtension extends Extension
26
{
27
    private static $allowed_actions = [
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
28
        'updateworkflow',
29
        'startworkflow'
30
    ];
31
32
    /**
33
     * @param array $data
34
     * @param Form $form
35
     * @param HTTPRequest $request
36
     * @return string|null
37
     */
38
    public function startworkflow($data, $form, $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

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

Loading history...
39
    {
40
        $item = $form->getRecord();
41
        $workflowID = isset($data['TriggeredWorkflowID']) ? intval($data['TriggeredWorkflowID']) : 0;
42
43
        if (!$item || !$item->canEdit()) {
44
            return null;
45
        }
46
47
        // Save a draft, if the user forgets to do so
48
        $this->saveAsDraftWithAction($form, $item);
49
50
        $service = singleton(WorkflowService::class);
51
        $service->startWorkflow($item, $workflowID);
52
53
        return $this->returnResponse($form);
54
    }
55
56
    /**
57
     * Need to update the edit form AFTER it's been transformed to read only so that the workflow stuff is still
58
     * allowed to be added with 'write' permissions
59
     *
60
     * @param Form $form
61
     */
62
    public function updateEditForm(Form $form)
63
    {
64
        Requirements::javascript('symbiote/silverstripe-advancedworkflow:client/dist/js/advancedworkflow.js');
65
        /** @var WorkflowService $service */
66
        $service = singleton(WorkflowService::class);
67
        /** @var DataObject|WorkflowApplicable $record */
68
        $record = $form->getRecord();
69
        $active = $service->getWorkflowFor($record);
70
71
        if ($active) {
72
            $fields = $form->Fields();
73
            $current = $active->CurrentAction();
74
            $wfFields = $active->getWorkflowFields();
75
76
            $allowed = array_keys($wfFields->saveableFields());
77
            $data = [];
78
            foreach ($allowed as $fieldName) {
79
                $data[$fieldName] = $current->$fieldName;
80
            }
81
82
            $fields->findOrMakeTab(
83
                'Root.WorkflowActions',
84
                _t('Workflow.WorkflowActionsTabTitle', 'Workflow Actions')
85
            );
86
            $fields->addFieldsToTab('Root.WorkflowActions', $wfFields);
87
88
            $form->loadDataFrom($data);
89
90
            // Set the form to readonly if the current user doesn't have permission to edit the record, and/or it
91
            // is in a state that requires review
92
            if (!$record->canEditWorkflow()) {
0 ignored issues
show
Bug introduced by
The method canEditWorkflow does only exist in Symbiote\AdvancedWorkflo...ions\WorkflowApplicable, but not in SilverStripe\ORM\DataObject.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
93
                if ($fields->hasMethod('isReadonly') && !$fields->isReadonly()) {
94
                    $fields->makeReadonly();
95
                } else {
96
                    $form->makeReadonly();
97
                }
98
            }
99
100
            $this->owner->extend('updateWorkflowEditForm', $form);
101
        }
102
    }
103
104
    /**
105
     * @param Form $form
106
     */
107
    public function updateItemEditForm($form)
108
    {
109
        /** @var DataObject $record */
110
        $record = $form->getRecord();
111
        if ($record && $record->hasExtension(WorkflowApplicable::class)) {
112
            $actions = $form->Actions();
113
            $record->extend('updateCMSActions', $actions);
114
            $this->updateEditForm($form);
115
        }
116
    }
117
118
    /**
119
     * Update a workflow based on user input.
120
     *
121
     * @todo refactor with WorkflowInstance::updateWorkflow
122
     *
123
     * @param array $data
124
     * @param Form $form
125
     * @param HTTPRequest $request
126
     * @return string|null
127
     */
128
    public function updateworkflow($data, Form $form, $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

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

Loading history...
129
    {
130
        /** @var WorkflowService $service */
131
        $service = singleton(WorkflowService::class);
132
        /** @var DataObject $record */
133
        $record = $form->getRecord();
134
        $workflow = $service->getWorkflowFor($record);
135
        if (!$workflow) {
136
            return null;
137
        }
138
139
        $action = $workflow->CurrentAction();
140
141
        if (!$record || !$record->canEditWorkflow()) {
142
            return null;
143
        }
144
145
        $allowedFields = $workflow->getWorkflowFields()->saveableFields();
146
        unset($allowedFields['TransitionID']);
147
148
        $allowed = array_keys($allowedFields);
149
        if (count($allowed)) {
150
            $form->saveInto($action, $allowed);
0 ignored issues
show
Documentation introduced by
$allowed is of type array, but the function expects a object<SilverStripe\Forms\FieldList>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
151
            $action->write();
152
        }
153
154
        if (isset($data['TransitionID']) && $data['TransitionID']) {
155
            $service->executeTransition($record, $data['TransitionID']);
156
        } else {
157
            // otherwise, just try to execute the current workflow to see if it
158
            // can now proceed based on user input
159
            $workflow->execute();
160
        }
161
162
        return $this->returnResponse($form);
163
    }
164
165
    protected function returnResponse($form)
166
    {
167
        if ($this->owner instanceof GridFieldDetailForm_ItemRequest) {
168
            $record = $form->getRecord();
169
            if ($record && $record->exists()) {
170
                return $this->owner->edit($this->owner->getRequest());
171
            }
172
        }
173
174
        $negotiator = method_exists($this->owner, 'getResponseNegotiator')
175
            ? $this->owner->getResponseNegotiator()
176
            : Controller::curr()->getResponseNegotiator();
177
        return $negotiator->respond($this->owner->getRequest());
178
    }
179
180
    /**
181
     * Ocassionally users forget to apply their changes via the standard CMS "Save Draft" button,
182
     * and select the action button instead - losing their changes.
183
     * Calling this from a controller method saves a draft automatically for the user, whenever a workflow action is run
184
     * See: #72 and #77
185
     *
186
     * @param Form $form
187
     * @param DataObject $item
188
     * @return void
189
     */
190
    protected function saveAsDraftWithAction(Form $form, DataObject $item)
191
    {
192
        $form->saveInto($item);
193
        $item->write();
194
    }
195
}
196