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 ( bf6f51...19227d )
by Robbie
56:02
created

WorkflowDefinition::setWorkflowService()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Symbiote\AdvancedWorkflow\DataObjects;
4
5
use SilverStripe\Control\Controller;
6
use SilverStripe\Forms\CheckboxSetField;
7
use SilverStripe\Forms\DropdownField;
8
use SilverStripe\Forms\FieldGroup;
9
use SilverStripe\Forms\FieldList;
10
use SilverStripe\Forms\FormAction;
11
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
12
use SilverStripe\Forms\GridField\GridField;
13
use SilverStripe\Forms\GridField\GridFieldAddNewButton;
14
use SilverStripe\Forms\GridField\GridFieldDeleteAction;
15
use SilverStripe\Forms\GridField\GridFieldEditButton;
16
use SilverStripe\Forms\GridField\GridFieldViewButton;
17
use SilverStripe\Forms\GridField\GridFieldDetailForm;
18
use SilverStripe\Forms\GridField\GridFieldConfig_Base;
19
use SilverStripe\Forms\LabelField;
20
use SilverStripe\Forms\LiteralField;
21
use SilverStripe\Forms\NumericField;
22
use SilverStripe\Forms\ReadonlyField;
23
use SilverStripe\Forms\TabSet;
24
use SilverStripe\Forms\TextareaField;
25
use SilverStripe\Forms\TextField;
26
use SilverStripe\Forms\TreeMultiselectField;
27
use SilverStripe\ORM\DataObject;
28
use SilverStripe\ORM\DB;
29
use SilverStripe\Security\Group;
30
use SilverStripe\Security\Member;
31
use SilverStripe\Security\Permission;
32
use SilverStripe\Security\Security;
33
use Symbiote\AdvancedWorkflow\FormFields\WorkflowField;
34
use Symbiote\AdvancedWorkflow\Services\WorkflowService;
35
use Symbiote\QueuedJobs\Services\AbstractQueuedJob;
36
37
/**
38
 * An overall definition of a workflow
39
 *
40
 * The workflow definition has a series of steps to it. Each step has a series of possible transitions
41
 * that it can take - the first one that meets certain criteria is followed, which could lead to
42
 * another step.
43
 *
44
 * A step is either manual or automatic; an example 'manual' step would be requiring a person to review
45
 * a document. An automatic step might be to email a group of people, or to publish documents.
46
 * Basically, a manual step requires the interaction of someone to pick which action to take, an automatic
47
 * step will automatically determine what to do once it has finished.
48
 *
49
 * @author  [email protected]
50
 * @license BSD License (http://silverstripe.org/bsd-license/)
51
 * @package advancedworkflow
52
 */
53
class WorkflowDefinition extends DataObject
54
{
55
    private static $db = [
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...
56
        'Title'                 => 'Varchar(128)',
57
        'Description'       => 'Text',
58
        'Template'          => 'Varchar',
59
        'TemplateVersion'   => 'Varchar',
60
        'RemindDays'        => 'Int',
61
        'Sort'              => 'Int',
62
        'InitialActionButtonText' => 'Varchar',
63
    ];
64
65
    private static $default_sort = 'Sort';
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...
66
67
    private static $has_many = [
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...
68
        'Actions'   => WorkflowAction::class,
69
        'Instances' => WorkflowInstance::class
70
    ];
71
72
    /**
73
     * By default, a workflow definition is bound to a particular set of users or groups.
74
     *
75
     * This is covered across to the workflow instance - it is up to subsequent
76
     * workflow actions to change this if needbe.
77
     *
78
     * @var array
79
     */
80
    private static $many_many = [
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...
81
        'Users' => Member::class,
82
        'Groups' => Group::class,
83
    ];
84
85
    private static $icon = 'symbiote/silverstripe-advancedworkflow:images/definition.png';
86
87
    public static $default_workflow_title_base = 'My Workflow';
88
89
    public static $workflow_defs = [];
90
91
    private static $dependencies = [
92
        'workflowService' => '%$' . WorkflowService::class,
93
    ];
94
95
    private static $table_name = 'WorkflowDefinition';
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...
96
97
    /**
98
     * @var WorkflowService
99
     */
100
    public $workflowService;
101
102
    /**
103
     * Gets the action that first triggers off the workflow
104
     *
105
     * @return WorkflowAction
106
     */
107
    public function getInitialAction()
108
    {
109
        if ($actions = $this->Actions()) {
0 ignored issues
show
Bug introduced by
The method Actions() does not exist on Symbiote\AdvancedWorkflo...ects\WorkflowDefinition. Did you maybe mean updateAdminActions()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
110
            return $actions->First();
111
        }
112
    }
113
114
    /**
115
     * Ensure a sort value is set and we get a useable initial workflow title.
116
     */
117
    public function onBeforeWrite()
118
    {
119
        if (!$this->Sort) {
0 ignored issues
show
Documentation introduced by
The property Sort does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
120
            $this->Sort = DB::query('SELECT MAX("Sort") + 1 FROM "WorkflowDefinition"')->value();
0 ignored issues
show
Documentation introduced by
The property Sort does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
121
        }
122
        if (!$this->ID && !$this->Title) {
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
123
            $this->Title = $this->getDefaultWorkflowTitle();
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
124
        }
125
126
        parent::onBeforeWrite();
127
    }
128
129
    /**
130
     * After we've been written, check whether we've got a template and to then
131
     * create the relevant actions etc.
132
     */
133
    public function onAfterWrite()
134
    {
135
        parent::onAfterWrite();
136
137
        // Request via ImportForm where TemplateVersion is already set, so unset it
138
        $posted = Controller::curr()->getRequest()->postVars();
139
        if (isset($posted['_CsvFile']) && $this->TemplateVersion) {
0 ignored issues
show
Documentation introduced by
The property TemplateVersion does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
140
            $this->TemplateVersion = null;
0 ignored issues
show
Documentation introduced by
The property TemplateVersion does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
141
        }
142
        if ($this->numChildren() == 0 && $this->Template && !$this->TemplateVersion) {
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
The property TemplateVersion does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
143
            $this->getWorkflowService()->defineFromTemplate($this, $this->Template);
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
144
        }
145
    }
146
147
    /**
148
     * Ensure all WorkflowDefinition relations are removed on delete. If we don't do this,
149
     * we see issues with targets previously under the control of a now-deleted workflow,
150
     * becoming stuck, even if a new workflow is subsequently assigned to it.
151
     *
152
     * @return null
153
     */
154
    public function onBeforeDelete()
155
    {
156
        parent::onBeforeDelete();
157
158
        // Delete related import
159
        $this->deleteRelatedImport();
160
161
        // Reset/unlink related HasMany|ManyMany relations and their orphaned objects
162
        $this->removeRelatedHasLists();
163
    }
164
165
    /**
166
     * Removes User+Group relations from this object as well as WorkflowAction relations.
167
     * When a WorkflowAction is deleted, its own relations are also removed:
168
     * - WorkflowInstance
169
     * - WorkflowTransition
170
     * @see WorkflowAction::onAfterDelete()
171
     *
172
     * @return void
173
     */
174
    private function removeRelatedHasLists()
175
    {
176
        $this->Users()->removeAll();
0 ignored issues
show
Documentation Bug introduced by
The method Users does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
177
        $this->Groups()->removeAll();
0 ignored issues
show
Documentation Bug introduced by
The method Groups does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
178
        $this->Actions()->each(function ($action) {
0 ignored issues
show
Bug introduced by
The method Actions() does not exist on Symbiote\AdvancedWorkflo...ects\WorkflowDefinition. Did you maybe mean updateAdminActions()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
179
            if ($orphan = DataObject::get_by_id(WorkflowAction::class, $action->ID)) {
180
                $orphan->delete();
181
            }
182
        });
183
    }
184
185
    /**
186
     *
187
     * Deletes related ImportedWorkflowTemplate objects.
188
     *
189
     * @return void
190
     */
191
    private function deleteRelatedImport()
192
    {
193
        if ($import = DataObject::get(ImportedWorkflowTemplate::class)->filter('DefinitionID', $this->ID)->first()) {
194
            $import->delete();
195
        }
196
    }
197
198
    /**
199
     * @return int
200
     */
201
    public function numChildren()
202
    {
203
        return $this->Actions()->count();
0 ignored issues
show
Bug introduced by
The method Actions() does not exist on Symbiote\AdvancedWorkflo...ects\WorkflowDefinition. Did you maybe mean updateAdminActions()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
204
    }
205
206
    public function fieldLabels($includerelations = true)
207
    {
208
        $labels = parent::fieldLabels($includerelations);
209
        $labels['Title'] = _t('WorkflowDefinition.TITLE', 'Title');
210
        $labels['Description'] = _t('WorkflowDefinition.DESCRIPTION', 'Description');
211
        $labels['Template'] = _t('WorkflowDefinition.TEMPLATE_NAME', 'Source Template');
212
        $labels['TemplateVersion'] = _t('WorkflowDefinition.TEMPLATE_VERSION', 'Template Version');
213
214
        return $labels;
215
    }
216
217
    public function getCMSFields()
218
    {
219
220
        $cmsUsers = Member::mapInCMSGroups();
221
222
        $fields = new FieldList(new TabSet('Root'));
223
224
        $fields->addFieldToTab('Root.Main', new TextField('Title', $this->fieldLabel('Title')));
225
        $fields->addFieldToTab('Root.Main', new TextareaField('Description', $this->fieldLabel('Description')));
226
        $fields->addFieldToTab('Root.Main', TextField::create(
227
            'InitialActionButtonText',
228
            _t('WorkflowDefinition.INITIAL_ACTION_BUTTON_TEXT', 'Initial Action Button Text')
229
        ));
230
        if ($this->ID) {
231
            $fields->addFieldToTab(
232
                'Root.Main',
233
                new CheckboxSetField('Users', _t('WorkflowDefinition.USERS', 'Users'), $cmsUsers)
234
            );
235
            $fields->addFieldToTab(
236
                'Root.Main',
237
                new TreeMultiselectField('Groups', _t('WorkflowDefinition.GROUPS', 'Groups'), Group::class)
238
            );
239
        }
240
241
        if (class_exists(AbstractQueuedJob::class)) {
242
            $fields->addFieldToTab(
243
                'Root.Main',
244
                NumericField::create(
245
                    'RemindDays',
246
                    _t('WorkflowDefinition.REMINDEREMAIL', 'Reminder Email')
247
                )->setDescription(_t(
248
                    __CLASS__ . '.ReminderEmailDescription',
249
                    'Send reminder email after the specified number of days without action.'
250
                ))
251
            );
252
        }
253
254
        if ($this->ID) {
255
            if ($this->Template) {
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
256
                $template = $this->getWorkflowService()->getNamedTemplate($this->Template);
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
257
                $fields->addFieldToTab(
258
                    'Root.Main',
259
                    new ReadonlyField('Template', $this->fieldLabel('Template'), $this->Template)
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
260
                );
261
                $fields->addFieldToTab(
262
                    'Root.Main',
263
                    new ReadonlyField(
264
                        'TemplateDesc',
265
                        _t('WorkflowDefinition.TEMPLATE_INFO', 'Template Info'),
266
                        $template ? $template->getDescription() : ''
267
                    )
268
                );
269
                $fields->addFieldToTab(
270
                    'Root.Main',
271
                    $tv = new ReadonlyField('TemplateVersion', $this->fieldLabel('TemplateVersion'))
272
                );
273
                $tv->setRightTitle(sprintf(_t(
274
                    'WorkflowDefinition.LATEST_VERSION',
275
                    'Latest version is %s'
276
                ), $template ? $template->getVersion() : ''));
277
            }
278
279
            $fields->addFieldToTab('Root.Main', new WorkflowField(
280
                'Workflow',
281
                _t('WorkflowDefinition.WORKFLOW', 'Workflow'),
282
                $this
283
            ));
284
        } else {
285
            // add in the 'template' info
286
            $templates = $this->getWorkflowService()->getTemplates();
287
288
            if (is_array($templates)) {
289
                $items = ['' => ''];
290
                foreach ($templates as $template) {
291
                    $items[$template->getName()] = $template->getName();
292
                }
293
                $templates = array_combine(array_keys($templates), array_keys($templates));
0 ignored issues
show
Unused Code introduced by
$templates is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
294
295
                $fields->addFieldToTab(
296
                    'Root.Main',
297
                    $dd = DropdownField::create(
298
                        'Template',
299
                        _t(
300
                            'WorkflowDefinition.CHOOSE_TEMPLATE',
301
                            'Choose template (optional)'
302
                        ),
303
                        $items
304
                    )
305
                );
306
                $dd->setHasEmptyDefault(true);
307
                $dd->setRightTitle(_t(
308
                    'WorkflowDefinition.CHOOSE_TEMPLATE_RIGHT',
309
                    'If set, this workflow definition will be automatically updated if the template is changed'
310
                ));
311
            }
312
313
            /*
314
             * Uncomment to allow pre-uploaded exports to appear in a new DropdownField.
315
             *
316
             * $import = singleton('WorkflowDefinitionImporter')->getImportedWorkflows();
317
             * if (is_array($import)) {
318
             *     $_imports = array('' => '');
319
             *     foreach ($imports as $import) {
320
             *         $_imports[$import->getName()] = $import->getName();
321
             *     }
322
             *     $imports = array_combine(array_keys($_imports), array_keys($_imports));
323
             *     $fields->addFieldToTab('Root.Main', new DropdownField('Import', _t(
324
             *         'WorkflowDefinition.CHOOSE_IMPORT',
325
             *         'Choose import (optional)'
326
             *     ), $imports));
327
             * }
328
             */
329
330
            $message = _t(
331
                'WorkflowDefinition.ADDAFTERSAVING',
332
                'You can add workflow steps after you save for the first time.'
333
            );
334
            $fields->addFieldToTab('Root.Main', new LiteralField(
335
                'AddAfterSaving',
336
                "<p class='message notice'>$message</p>"
337
            ));
338
        }
339
340
        if ($this->ID && Permission::check('VIEW_ACTIVE_WORKFLOWS')) {
341
            $active = $this->Instances()->filter([
0 ignored issues
show
Bug introduced by
The method Instances() does not exist on Symbiote\AdvancedWorkflo...ects\WorkflowDefinition. Did you maybe mean getExtensionInstances()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
342
                'WorkflowStatus' => ['Active', 'Paused']
343
            ]);
344
345
            $active = new GridField(
346
                'Active',
347
                _t('WorkflowDefinition.WORKFLOWACTIVEIINSTANCES', 'Active Workflow Instances'),
348
                $active,
349
                new GridFieldConfig_RecordEditor()
350
            );
351
352
            $active->getConfig()->removeComponentsByType(GridFieldAddNewButton::class);
353
            $active->getConfig()->removeComponentsByType(GridFieldDeleteAction::class);
354
355
            if (!Permission::check('REASSIGN_ACTIVE_WORKFLOWS')) {
356
                $active->getConfig()->removeComponentsByType(GridFieldEditButton::class);
357
                $active->getConfig()->addComponent(new GridFieldViewButton());
358
                $active->getConfig()->addComponent(new GridFieldDetailForm());
359
            }
360
361
            $completed = $this->Instances()->filter([
0 ignored issues
show
Bug introduced by
The method Instances() does not exist on Symbiote\AdvancedWorkflo...ects\WorkflowDefinition. Did you maybe mean getExtensionInstances()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
362
                'WorkflowStatus' => ['Complete', 'Cancelled']
363
            ]);
364
365
            $config = new GridFieldConfig_Base();
366
            $config->addComponent(new GridFieldEditButton());
367
            $config->addComponent(new GridFieldDetailForm());
368
369
            $completed = new GridField(
370
                'Completed',
371
                _t('WorkflowDefinition.WORKFLOWCOMPLETEDIINSTANCES', 'Completed Workflow Instances'),
372
                $completed,
373
                $config
374
            );
375
376
            $fields->findOrMakeTab(
377
                'Root.Active',
378
                _t('WorkflowEmbargoExpiryExtension.ActiveWorkflowStateTitle', 'Active')
379
            );
380
            $fields->addFieldToTab('Root.Active', $active);
381
382
            $fields->findOrMakeTab(
383
                'Root.Completed',
384
                _t('WorkflowEmbargoExpiryExtension.CompletedWorkflowStateTitle', 'Completed')
385
            );
386
            $fields->addFieldToTab('Root.Completed', $completed);
387
        }
388
389
        $this->extend('updateCMSFields', $fields);
390
391
        return $fields;
392
    }
393
394
    public function updateAdminActions($actions)
395
    {
396
        if ($this->Template) {
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
397
            $template = $this->getWorkflowService()->getNamedTemplate($this->Template);
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
398
            if ($template && $this->TemplateVersion != $template->getVersion()) {
0 ignored issues
show
Documentation introduced by
The property TemplateVersion does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
399
                $label = sprintf(_t(
400
                    'WorkflowDefinition.UPDATE_FROM_TEMLPATE',
401
                    'Update to latest template version (%s)'
402
                ), $template->getVersion());
403
                $actions->push($action = FormAction::create('updatetemplateversion', $label));
404
            }
405
        }
406
    }
407
408
    public function updateFromTemplate()
409
    {
410
        if ($this->Template) {
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
411
            $template = $this->getWorkflowService()->getNamedTemplate($this->Template);
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
412
            $template->updateDefinition($this);
413
        }
414
    }
415
416
    /**
417
     * If a workflow-title doesn't already exist, we automatically create a suitable default title
418
     * when users attempt to create title-less workflow definitions or upload/create Workflows that would
419
     * otherwise have the same name.
420
     *
421
     * @return string
422
     * @todo    Filter query on current-user's workflows. Avoids confusion when other users may already have
423
     *          'My Workflow 1' and user sees 'My Workflow 2'
424
     */
425
    public function getDefaultWorkflowTitle()
426
    {
427
        // Where is the title coming from that we wish to test?
428
        $incomingTitle = $this->incomingTitle();
429
        $defs = WorkflowDefinition::get()->map()->toArray();
430
        $tmp = [];
431
432
        foreach ($defs as $def) {
433
            $parts = preg_split("#\s#", $def, -1, PREG_SPLIT_NO_EMPTY);
434
            $lastPart = array_pop($parts);
435
            $match = implode(' ', $parts);
436
            // @todo do all this in one preg_match_all() call
437
            if (preg_match("#$match#", $incomingTitle)) {
438
                // @todo use a simple incrementer??
439
                if ($incomingTitle.' '.$lastPart == $def) {
440
                    array_push($tmp, $lastPart);
441
                }
442
            }
443
        }
444
445
        $incr = 1;
446
        if (count($tmp)) {
447
            sort($tmp, SORT_NUMERIC);
448
            $incr = (int)end($tmp)+1;
449
        }
450
        return $incomingTitle.' '.$incr;
451
    }
452
453
    /**
454
     * Return the workflow definition title according to the source
455
     *
456
     * @return string
457
     */
458
    public function incomingTitle()
459
    {
460
        $req = Controller::curr()->getRequest();
461
        if (isset($req['_CsvFile']['name']) && !empty($req['_CsvFile']['name'])) {
462
            $import = ImportedWorkflowTemplate::get()->filter('Filename', $req['_CsvFile']['name'])->first();
463
            $incomingTitle = $import->Name;
464
        } elseif (isset($req['Template']) && !empty($req['Template'])) {
465
            $incomingTitle = $req['Template'];
466
        } elseif (isset($req['Title']) && !empty($req['Title'])) {
467
            $incomingTitle = $req['Title'];
468
        } else {
469
            $incomingTitle = self::$default_workflow_title_base;
470
        }
471
        return $incomingTitle;
472
    }
473
474
    /**
475
     * Determines if target can be published directly when no workflow has started yet
476
     * Opens extension hook to allow an extension to determine if this is allowed as well
477
     *
478
     * By default returns false
479
     *
480
     * @param $member
481
     * @param $target
482
     * @return Boolean
483
     */
484
    public function canWorkflowPublish($member, $target)
485
    {
486
        $publish = $this->extendedCan('canWorkflowPublish', $member, $target);
487
        if (is_null($publish)) {
488
            $publish = Permission::checkMember($member, 'ADMIN');
489
        }
490
        return $publish;
491
    }
492
493
    /**
494
     *
495
     * @param Member $member
496
     * @param array $context
497
     * @return bool
498
     */
499 View Code Duplication
    public function canCreate($member = null, $context = [])
0 ignored issues
show
Duplication introduced by
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...
500
    {
501
        if (is_null($member)) {
502
            if (!Security::getCurrentUser()) {
503
                return false;
504
            }
505
            $member = Security::getCurrentUser();
506
        }
507
        return Permission::checkMember($member, 'CREATE_WORKFLOW');
508
    }
509
510
    /**
511
     *
512
     * @param Member $member
513
     * @return boolean
514
     */
515
    public function canView($member = null)
516
    {
517
        return $this->userHasAccess($member);
0 ignored issues
show
Bug introduced by
It seems like $member defined by parameter $member on line 515 can be null; however, Symbiote\AdvancedWorkflo...nition::userHasAccess() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
518
    }
519
520
    /**
521
     *
522
     * @param Member $member
523
     * @return boolean
524
     */
525
    public function canEdit($member = null)
526
    {
527
        return $this->canCreate($member);
528
    }
529
530
    /**
531
     *
532
     * @param Member $member
533
     * @return boolean
534
     * @see {@link $this->onBeforeDelete()}
535
     */
536 View Code Duplication
    public function canDelete($member = null)
0 ignored issues
show
Duplication introduced by
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...
537
    {
538
        if (!$member) {
539
            if (!Security::getCurrentUser()) {
540
                return false;
541
            }
542
            $member = Security::getCurrentUser();
543
        }
544
545
        if (Permission::checkMember($member, 'ADMIN')) {
546
            return true;
547
        }
548
549
        /*
550
         * DELETE_WORKFLOW should trump all other canDelete() return values on
551
         * related objects.
552
         * @see {@link $this->onBeforeDelete()}
553
         */
554
        return Permission::checkMember($member, 'DELETE_WORKFLOW');
555
    }
556
557
    /**
558
     * Checks whether the passed user is able to view this ModelAdmin
559
     *
560
     * @param Member $member
561
     * @return bool
562
     */
563 View Code Duplication
    protected function userHasAccess($member)
0 ignored issues
show
Duplication introduced by
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...
564
    {
565
        if (!$member) {
566
            if (!Security::getCurrentUser()) {
567
                return false;
568
            }
569
            $member = Security::getCurrentUser();
570
        }
571
572
        if (Permission::checkMember($member, "VIEW_ACTIVE_WORKFLOWS")) {
573
            return true;
574
        }
575
    }
576
577
    /**
578
     * @param WorkflowService $workflowService
579
     * @return $this
580
     */
581
    public function setWorkflowService(WorkflowService $workflowService)
582
    {
583
        $this->workflowService = $workflowService;
584
        return $this;
585
    }
586
587
    /**
588
     * @return WorkflowService
589
     */
590
    public function getWorkflowService()
591
    {
592
        return $this->workflowService;
593
    }
594
}
595