WorkflowDefinition::updateAdminActions()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 9
rs 9.2
cc 4
eloc 6
nc 3
nop 1
1
<?php
2
/**
3
 * An overall definition of a workflow
4
 *
5
 * The workflow definition has a series of steps to it. Each step has a series of possible transitions
6
 * that it can take - the first one that meets certain criteria is followed, which could lead to
7
 * another step.
8
 *
9
 * A step is either manual or automatic; an example 'manual' step would be requiring a person to review
10
 * a document. An automatic step might be to email a group of people, or to publish documents.
11
 * Basically, a manual step requires the interaction of someone to pick which action to take, an automatic
12
 * step will automatically determine what to do once it has finished.
13
 *
14
 * @author  [email protected]
15
 * @license BSD License (http://silverstripe.org/bsd-license/)
16
 * @package advancedworkflow
17
 */
18
class WorkflowDefinition extends DataObject {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
19
20
	private static $db = array(
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...
Unused Code introduced by
The property $db 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...
21
		'Title'				=> 'Varchar(128)',
22
		'Description'		=> 'Text',
23
		'Template'			=> 'Varchar',
24
		'TemplateVersion'	=> 'Varchar',
25
		'RemindDays'		=> 'Int',
26
		'Sort'				=> 'Int',
27
		'InitialActionButtonText' => 'Varchar'
28
	);
29
30
	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...
Unused Code introduced by
The property $default_sort 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...
31
32
	private static $has_many = array(
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...
Unused Code introduced by
The property $has_many 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...
33
		'Actions'   => 'WorkflowAction',
34
		'Instances' => 'WorkflowInstance'
35
	);
36
37
	/**
38
	 * By default, a workflow definition is bound to a particular set of users or groups.
39
	 *
40
	 * This is covered across to the workflow instance - it is up to subsequent
41
	 * workflow actions to change this if needbe.
42
	 *
43
	 * @var array
44
	 */
45
	private static $many_many = array(
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...
Unused Code introduced by
The property $many_many 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...
46
		'Users' => 'Member',
47
		'Groups' => 'Group'
48
	);
49
50
	public static $icon = 'advancedworkflow/images/definition.png';
51
52
	public static $default_workflow_title_base = 'My Workflow';
53
54
	public static $workflow_defs = array();
55
56
	private static $dependencies = array(
0 ignored issues
show
Unused Code introduced by
The property $dependencies 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...
57
		'workflowService'		=> '%$WorkflowService',
58
	);
59
60
	/**
61
	 * @var WorkflowService
62
	 */
63
	public $workflowService;
64
65
	/**
66
	 * Gets the action that first triggers off the workflow
67
	 *
68
	 * @return WorkflowAction
69
	 */
70
	public function getInitialAction() {
71
		if($actions = $this->Actions()) return $actions->First();
0 ignored issues
show
Bug introduced by
The method Actions() does not exist on 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...
72
	}
73
74
	/**
75
	 * Ensure a sort value is set and we get a useable initial workflow title.
76
	 */
77
	public function onBeforeWrite() {
78
		if(!$this->Sort) {
0 ignored issues
show
Documentation introduced by
The property Sort does not exist on object<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...
79
			$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<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...
80
		}
81
		if(!$this->ID) {
82
			$this->Title = $this->getDefaultWorkflowTitle();
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<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...
83
		}
84
		parent::onBeforeWrite();
85
	}
86
87
	/**
88
	 * After we've been written, check whether we've got a template and to then
89
	 * create the relevant actions etc.
90
	 */
91
	public function onAfterWrite() {
92
		parent::onAfterWrite();
93
94
		// Request via ImportForm where TemplateVersion is already set, so unset it
95
		$posted = Controller::curr()->getRequest()->postVars();
96
		if(isset($posted['_CsvFile']) && $this->TemplateVersion) {
0 ignored issues
show
Documentation introduced by
The property TemplateVersion does not exist on object<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...
97
			$this->TemplateVersion = null;
0 ignored issues
show
Documentation introduced by
The property TemplateVersion does not exist on object<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...
98
		}
99
		if($this->numChildren() == 0 && $this->Template && !$this->TemplateVersion) {
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<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<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...
100
			$this->workflowService->defineFromTemplate($this, $this->Template);
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<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...
101
		}
102
	}
103
104
	/**
105
	 * Ensure all WorkflowDefinition relations are removed on delete. If we don't do this,
106
	 * we see issues with targets previously under the control of a now-deleted workflow,
107
	 * becoming stuck, even if a new workflow is subsequently assigned to it.
108
	 *
109
	 * @return null
110
	 */
111
	public function onBeforeDelete() {
112
		parent::onBeforeDelete();
113
114
		// Delete related import
115
		$this->deleteRelatedImport();
116
117
		// Reset/unlink related HasMany|ManyMany relations and their orphaned objects
118
		$this->removeRelatedHasLists();
119
	}
120
121
	/**
122
	 * Removes User+Group relations from this object as well as WorkflowAction relations.
123
	 * When a WorkflowAction is deleted, its own relations are also removed:
124
	 * - WorkflowInstance
125
	 * - WorkflowTransition
126
	 * @see WorkflowAction::onAfterDelete()
127
	 *
128
	 * @return void
129
	 */
130
	private function removeRelatedHasLists() {
131
		$this->Users()->removeAll();
0 ignored issues
show
Documentation Bug introduced by
The method Users does not exist on object<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...
132
		$this->Groups()->removeAll();
0 ignored issues
show
Documentation Bug introduced by
The method Groups does not exist on object<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...
133
		$this->Actions()->each(function($action) {
0 ignored issues
show
Bug introduced by
The method Actions() does not exist on 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...
134
			if($orphan = DataObject::get_by_id('WorkflowAction', $action->ID)) {
135
				$orphan->delete();
136
			}
137
		});
138
	}
139
140
	/**
141
	 *
142
	 * Deletes related ImportedWorkflowTemplate objects.
143
	 *
144
	 * @return void
145
	 */
146
	private function deleteRelatedImport() {
147
		if($import = DataObject::get('ImportedWorkflowTemplate')->filter('DefinitionID', $this->ID)->first()) {
148
			$import->delete();
149
		}
150
	}
151
152
	/**
153
	 * @return int
154
	 */
155
	public function numChildren() {
156
		return count($this->Actions());
0 ignored issues
show
Bug introduced by
The method Actions() does not exist on 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...
157
	}
158
159
	public function fieldLabels($includerelations = true) {
160
		$labels = parent::fieldLabels($includerelations);
161
		$labels['Title'] = _t('WorkflowDefinition.TITLE', 'Title');
162
		$labels['Description'] = _t('WorkflowDefinition.DESCRIPTION', 'Description');
163
		$labels['Template'] = _t('WorkflowDefinition.TEMPLATE_NAME', 'Source Template');
164
		$labels['TemplateVersion'] = _t('WorkflowDefinition.TEMPLATE_VERSION', 'Template Version');
165
166
		return $labels;
167
	}
168
169
	public function getCMSFields() {
170
171
		$cmsUsers = Member::mapInCMSGroups();
172
173
		$fields = new FieldList(new TabSet('Root'));
174
175
		$fields->addFieldToTab('Root.Main', new TextField('Title', $this->fieldLabel('Title')));
176
		$fields->addFieldToTab('Root.Main', new TextareaField('Description', $this->fieldLabel('Description')));
177
		$fields->addFieldToTab('Root.Main', TextField::create(
178
			'InitialActionButtonText',
179
			_t('WorkflowDefinition.INITIAL_ACTION_BUTTON_TEXT', 'Initial Action Button Text')
180
		));
181
		if($this->ID) {
182
			$fields->addFieldToTab('Root.Main', new CheckboxSetField('Users', _t('WorkflowDefinition.USERS', 'Users'), $cmsUsers));
183
			$fields->addFieldToTab('Root.Main', new TreeMultiselectField('Groups', _t('WorkflowDefinition.GROUPS', 'Groups'), 'Group'));
184
		}
185
186
		if (class_exists('AbstractQueuedJob')) {
187
			$before = _t('WorkflowDefinition.SENDREMINDERDAYSBEFORE', 'Send reminder email after ');
188
			$after  = _t('WorkflowDefinition.SENDREMINDERDAYSAFTER', ' days without action.');
189
190
			$fields->addFieldToTab('Root.Main', new FieldGroup(
191
				_t('WorkflowDefinition.REMINDEREMAIL', 'Reminder Email'),
192
				new LabelField('ReminderEmailBefore', $before),
193
				new NumericField('RemindDays', ''),
194
				new LabelField('ReminderEmailAfter', $after)
195
			));
196
		}
197
198
		if($this->ID) {
199
			if ($this->Template) {
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<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...
200
				$template = $this->workflowService->getNamedTemplate($this->Template);
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<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...
201
				$fields->addFieldToTab('Root.Main', new ReadonlyField('Template', $this->fieldLabel('Template'), $this->Template));
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<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...
202
				$fields->addFieldToTab('Root.Main', new ReadonlyField('TemplateDesc', _t('WorkflowDefinition.TEMPLATE_INFO', 'Template Info'), $template ? $template->getDescription() : ''));
203
				$fields->addFieldToTab('Root.Main', $tv = new ReadonlyField('TemplateVersion', $this->fieldLabel('TemplateVersion')));
204
				$tv->setRightTitle(sprintf(_t('WorkflowDefinition.LATEST_VERSION', 'Latest version is %s'), $template ? $template->getVersion() : ''));
205
206
			}
207
208
			$fields->addFieldToTab('Root.Main', new WorkflowField(
209
				'Workflow', _t('WorkflowDefinition.WORKFLOW', 'Workflow'), $this
210
			));
211
		} else {
212
			// add in the 'template' info
213
			$templates = $this->workflowService->getTemplates();
214
215
			if (is_array($templates)) {
216
				$items = array('' => '');
217
				foreach ($templates as $template) {
218
					$items[$template->getName()] = $template->getName();
219
				}
220
				$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...
221
222
				$fields->addFieldToTab('Root.Main', $dd = new DropdownField('Template', _t('WorkflowDefinition.CHOOSE_TEMPLATE', 'Choose template (optional)'), $items));
223
				$dd->setRightTitle(_t('WorkflowDefinition.CHOOSE_TEMPLATE_RIGHT', 'If set, this workflow definition will be automatically updated if the template is changed'));
224
			}
225
226
			/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
49% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
227
			 * Uncomment to allow pre-uploaded exports to appear in a new DropdownField.
228
			 *
229
			 * $import = singleton('WorkflowDefinitionImporter')->getImportedWorkflows();
230
			 * if (is_array($import)) {
231
			 * $_imports = array('' => '');
232
			 * foreach ($imports as $import) {
233
			 * 		$_imports[$import->getName()] = $import->getName();
234
			 * }
235
			 * $imports = array_combine(array_keys($_imports), array_keys($_imports));
236
			 * $fields->addFieldToTab('Root.Main', new DropdownField('Import', _t('WorkflowDefinition.CHOOSE_IMPORT', 'Choose import (optional)'), $imports));
237
			 * }
238
			 */
239
240
			$message = _t(
241
				'WorkflowDefinition.ADDAFTERSAVING',
242
				'You can add workflow steps after you save for the first time.'
243
			);
244
			$fields->addFieldToTab('Root.Main', new LiteralField(
245
				'AddAfterSaving', "<p class='message notice'>$message</p>"
246
			));
247
		}
248
249
		if($this->ID && Permission::check('VIEW_ACTIVE_WORKFLOWS')) {
250
			$active = $this->Instances()->filter(array(
0 ignored issues
show
Bug introduced by
The method Instances() does not exist on 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...
251
				'WorkflowStatus' => array('Active', 'Paused')
252
			));
253
254
			$active = new GridField(
255
				'Active',
256
				_t('WorkflowDefinition.WORKFLOWACTIVEIINSTANCES', 'Active Workflow Instances'),
257
				$active,
258
				new GridFieldConfig_RecordEditor());
259
260
			$active->getConfig()->removeComponentsByType('GridFieldAddNewButton');
261
			$active->getConfig()->removeComponentsByType('GridFieldDeleteAction');
262
263
			if(!Permission::check('REASSIGN_ACTIVE_WORKFLOWS')) {
264
				$active->getConfig()->removeComponentsByType('GridFieldEditButton');
265
				$active->getConfig()->addComponent(new GridFieldViewButton());
266
				$active->getConfig()->addComponent(new GridFieldDetailForm());
267
			}
268
269
			$completed = $this->Instances()->filter(array(
0 ignored issues
show
Bug introduced by
The method Instances() does not exist on 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...
270
				'WorkflowStatus' => array('Complete', 'Cancelled')
271
			));
272
273
			$config = new GridFieldConfig_Base();
274
			$config->addComponent(new GridFieldEditButton());
275
			$config->addComponent(new GridFieldDetailForm());
276
277
			$completed = new GridField(
278
				'Completed',
279
				_t('WorkflowDefinition.WORKFLOWCOMPLETEDIINSTANCES', 'Completed Workflow Instances'),
280
				$completed,
281
				$config);
282
283
			$fields->findOrMakeTab(
284
				'Root.Active',
285
				_t('WorkflowEmbargoExpiryExtension.ActiveWorkflowStateTitle', 'Active')
286
			);
287
			$fields->addFieldToTab('Root.Active', $active);
288
289
			$fields->findOrMakeTab(
290
				'Root.Completed',
291
				_t('WorkflowEmbargoExpiryExtension.CompletedWorkflowStateTitle', 'Completed')
292
			);
293
			$fields->addFieldToTab('Root.Completed', $completed);
294
		}
295
296
		$this->extend('updateCMSFields', $fields);
297
298
		return $fields;
299
	}
300
301
	public function updateAdminActions($actions) {
302
		if ($this->Template) {
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<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...
303
			$template = $this->workflowService->getNamedTemplate($this->Template);
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<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...
304
			if ($template && $this->TemplateVersion != $template->getVersion()) {
0 ignored issues
show
Documentation introduced by
The property TemplateVersion does not exist on object<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...
305
				$label = sprintf(_t('WorkflowDefinition.UPDATE_FROM_TEMLPATE', 'Update to latest template version (%s)'), $template->getVersion());
306
				$actions->push($action = FormAction::create('updatetemplateversion', $label));
307
			}
308
		}
309
	}
310
311
	public function updateFromTemplate() {
312
		if ($this->Template) {
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<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...
313
			$template = $this->workflowService->getNamedTemplate($this->Template);
0 ignored issues
show
Documentation introduced by
The property Template does not exist on object<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...
314
			$template->updateDefinition($this);
315
		}
316
	}
317
318
	/**
319
	 * If a workflow-title doesn't already exist, we automatically create a suitable default title
320
	 * when users attempt to create title-less workflow definitions or upload/create Workflows that would
321
	 * otherwise have the same name.
322
	 *
323
	 * @return string
324
	 * @todo	Filter query on current-user's workflows. Avoids confusion when other users may already have 'My Workflow 1'
325
	 *			and user sees 'My Workflow 2'
326
	 */
327
	public function getDefaultWorkflowTitle() {
328
		// Where is the title coming from that we wish to test?
329
		$incomingTitle = $this->incomingTitle();
330
		$defs = DataObject::get('WorkflowDefinition')->map()->toArray();
331
		$tmp = array();
332
333
		foreach($defs as $def) {
334
			$parts = preg_split("#\s#", $def, -1, PREG_SPLIT_NO_EMPTY);
335
			$lastPart = array_pop($parts);
336
			$match = implode(' ', $parts);
337
			// @todo do all this in one preg_match_all() call
338
			if(preg_match("#$match#", $incomingTitle)) {
339
				// @todo use a simple incrementer??
340
				if($incomingTitle.' '.$lastPart == $def) {
341
					array_push($tmp, $lastPart);
342
				}
343
			}
344
		}
345
346
		$incr = 1;
347
		if(count($tmp)) {
348
			sort($tmp,SORT_NUMERIC);
349
			$incr = (int)end($tmp)+1;
350
		}
351
		return $incomingTitle.' '.$incr;
352
	}
353
354
	/**
355
	 * Return the workflow definition title according to the source
356
	 *
357
	 * @return string
358
	 */
359
	public function incomingTitle() {
360
		$req = Controller::curr()->getRequest();
361
		if(isset($req['_CsvFile']['name']) && !empty($req['_CsvFile']['name'])) {
362
			$import = DataObject::get('ImportedWorkflowTemplate')->filter('Filename', $req['_CsvFile']['name'])->first();
363
			$incomingTitle = $import->Name;
364
		}
365
		else if(isset($req['Template']) && !empty($req['Template'])) {
366
			$incomingTitle = $req['Template'];
367
		}
368
		else if(isset($req['Title']) && !empty($req['Title'])) {
369
			$incomingTitle = $req['Title'];
370
		}
371
		else {
372
			$incomingTitle = self::$default_workflow_title_base;
373
		}
374
		return $incomingTitle;
375
	}
376
377
	/**
378
	 *
379
	 * @param Member $member
380
	 * @return boolean
381
	 */
382 View Code Duplication
	public function canCreate($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...
383
		if (is_null($member)) {
384
			if (!Member::currentUserID()) {
385
				return false;
386
			}
387
			$member = Member::currentUser();
388
		}
389
		return Permission::checkMember($member, 'CREATE_WORKFLOW');
390
	}
391
392
	/**
393
	 *
394
	 * @param Member $member
395
	 * @return boolean
396
	 */
397
	public function canView($member=null) {
398
		return $this->userHasAccess($member);
399
	}
400
401
	/**
402
	 *
403
	 * @param Member $member
404
	 * @return boolean
405
	 */
406
	public function canEdit($member=null) {
407
		return $this->canCreate($member);
408
	}
409
410
	/**
411
	 *
412
	 * @param Member $member
413
	 * @return boolean
414
	 * @see {@link $this->onBeforeDelete()}
415
	 */
416 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...
417
		if(!$member) {
418
			if(!Member::currentUserID()) {
419
				return false;
420
			}
421
			$member = Member::currentUser();
422
		}
423
424
		if(Permission::checkMember($member, 'ADMIN')) {
425
			return true;
426
		}
427
428
		/*
429
		 * DELETE_WORKFLOW should trump all other canDelete() return values on
430
		 * related objects.
431
		 * @see {@link $this->onBeforeDelete()}
432
		 */
433
		return Permission::checkMember($member, 'DELETE_WORKFLOW');
434
	}
435
436
	/**
437
	 * Checks whether the passed user is able to view this ModelAdmin
438
	 *
439
	 * @param $memberID
440
	 */
441 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...
442
		if (!$member) {
443
			if (!Member::currentUserID()) {
444
				return false;
445
			}
446
			$member = Member::currentUser();
447
		}
448
449
		if(Permission::checkMember($member, "VIEW_ACTIVE_WORKFLOWS")) {
450
			return true;
451
		}
452
	}
453
}
454