Issues (621)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

code/dataobjects/WorkflowAction.php (11 issues)

Upgrade to new PHP Analysis Engine

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

1
<?php
2
/**
3
 * A workflow action describes a the 'state' a workflow can be in, and
4
 * the action(s) that occur while in that state. An action can then have
5
 * subsequent transitions out of the current state.
6
 *
7
 * @author  [email protected]
8
 * @license BSD License (http://silverstripe.org/bsd-license/)
9
 * @package advancedworkflow
10
 */
11
class WorkflowAction extends DataObject {
12
13
	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...
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...
14
		'Title'				=> 'Varchar(255)',
15
		'Comment'			=> 'Text',
16
		'Type'				=> "Enum('Dynamic,Manual','Manual')",  // is this used?
17
		'Executed'			=> 'Boolean',
18
		'AllowEditing'		=> "Enum('By Assignees,Content Settings,No','No')",		// can this item be edited?
19
		'Sort'				=> 'Int',
20
		'AllowCommenting'	=> 'Boolean'
21
	);
22
23
	private static $defaults = 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...
The property $defaults 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...
24
		'AllowCommenting'	=> '1',
25
	);
26
27
	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...
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...
28
29
	private static $has_one = 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...
The property $has_one 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...
30
		'WorkflowDef' => 'WorkflowDefinition',
31
		'Member'      => 'Member'
32
	);
33
34
	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...
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...
35
		'Transitions' => 'WorkflowTransition.Action'
36
	);
37
38
	/**
39
	 * The type of class to use for instances of this workflow action that are used for storing the
40
	 * data of the instance.
41
	 *
42
	 * @var string
43
	 */
44
	private static $instance_class = 'WorkflowActionInstance';
0 ignored issues
show
The property $instance_class 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...
45
46
	public static $icon = 'advancedworkflow/images/action.png';
47
48
	/**
49
	 * Can documents in the current workflow state be edited?
50
	 *
51
	 * Only return true or false if this is an absolute value; the WorkflowActionInstance
52
	 * will try and figure out an appropriate value for the actively running workflow
53
	 * if null is returned from this method.
54
	 *
55
	 * @param  DataObject $target
56
	 * @return bool
57
	 */
58
	public function canEditTarget(DataObject $target) {
59
		return null;
60
	}
61
62
	/**
63
	 * Does this action restrict viewing of the document?
64
	 *
65
	 * @param  DataObject $target
66
	 * @return bool
67
	 */
68
	public function canViewTarget(DataObject $target) {
69
		return null;
70
	}
71
72
	/**
73
	 * Does this action restrict the publishing of a document?
74
	 *
75
	 * @param  DataObject $target
76
	 * @return bool
77
	 */
78
	public function canPublishTarget(DataObject $target) {
79
		return null;
80
	}
81
82
	/**
83
	 * Allows users who have permission to create a WorkflowDefinition, to create actions on it too.
84
	 *
85
	 * @param  Member $member
86
	 * @return bool
87
	 */
88
	public function canCreate($member = null) {
89
		return $this->WorkflowDef()->canCreate($member);
90
	}
91
92
	/**
93
	 * @param  Member $member
94
	 * @return bool
95
	 */
96
	public function canEdit($member = null) {
97
		return $this->canCreate($member);
98
	}
99
100
	/**
101
	 * @param  Member $member
102
	 * @return bool
103
	 */
104
	public function canDelete($member = null) {
105
		return $this->WorkflowDef()->canDelete($member);
106
	}
107
108
	/*
109
	 * If there is only a single action defined for a workflow, there's no sense
110
	 * in allowing users to add a transition to it (and causing errors).
111
	 * Hide the "Add Transition" button in this case
112
	 *
113
	 * @return boolean true if we should disable the button, false otherwise
114
	 */
115
	public function canAddTransition() {
116
		return ($this->WorkflowDef()->numChildren() >1);
117
	}
118
119
	/**
120
	 * Gets an object that is used for saving the actual state of things during
121
	 * a running workflow. It still uses the workflow action def for managing the
122
	 * functional execution, however if you need to store additional data for
123
	 * the state, you can specify your own WorkflowActionInstance instead of
124
	 * the default to capture these elements
125
	 *
126
	 * @return WorkflowActionInstance
127
	 */
128
	public function getInstanceForWorkflow() {
129
		$instanceClass = $this->stat('instance_class');
130
		$instance = new $instanceClass();
131
		$instance->BaseActionID = $this->ID;
132
		return $instance;
133
	}
134
135
	/**
136
	 * Perform whatever needs to be done for this action. If this action can be considered executed, then
137
	 * return true - if not (ie it needs some user input first), return false and 'execute' will be triggered
138
	 * again at a later point in time after the user has provided more data, either directly or indirectly.
139
	 *
140
	 * @param  WorkflowInstance $workflow
141
	 * @return bool Returns true if this action has finished.
142
	 */
143
	public function execute(WorkflowInstance $workflow) {
144
		return true;
145
	}
146
147
	public function onBeforeWrite() {
148
		if(!$this->Sort) {
149
			$this->Sort = DB::query('SELECT MAX("Sort") + 1 FROM "WorkflowAction"')->value();
150
		}
151
152
		parent::onBeforeWrite();
153
	}
154
155
	/**
156
	 * When deleting an action from a workflow definition, make sure that workflows currently paused on that action
157
	 * are deleted
158
	 * Also removes all outbound transitions
159
	 */
160
	public function onAfterDelete() {
161
		parent::onAfterDelete();
162
		$wfActionInstances = WorkflowActionInstance::get()
163
				->leftJoin("WorkflowInstance",'"WorkflowInstance"."ID" = "WorkflowActionInstance"."WorkflowID"')
164
				->where(sprintf('"BaseActionID" = %d AND ("WorkflowStatus" IN (\'Active\',\'Paused\'))', $this->ID));
165
		foreach ($wfActionInstances as $wfActionInstance){
166
			$wfInstances = WorkflowInstance::get()->filter('CurrentActionID', $wfActionInstance->ID);
167
			foreach ($wfInstances as $wfInstance){
168
				$wfInstance->Groups()->removeAll();
169
				$wfInstance->Users()->removeAll();
170
				$wfInstance->delete();
171
			}
172
			$wfActionInstance->delete();
173
		}
174
		// Delete outbound transitions
175
		$transitions = WorkflowTransition::get()->filter('ActionID', $this->ID);
176
		foreach ($transitions as $transition){
177
			$transition->Groups()->removeAll();
178
			$transition->Users()->removeAll();
179
			$transition->delete();
180
		}
181
	}
182
183
	/**
184
	 * Called when the current target of the workflow has been updated
185
	 */
186
	public function targetUpdated(WorkflowInstance $workflow) {
187
	}
188
189
	/* CMS RELATED FUNCTIONALITY... */
190
191
192
	public function numChildren() {
193
		return count($this->Transitions());
194
	}
195
196
	public function getCMSFields() {
197
198
		$fields = new FieldList(new TabSet('Root'));
199
		$typeLabel = _t('WorkflowAction.CLASS_LABEL', 'Action Class');
200
		$fields->addFieldToTab('Root.Main', new ReadOnlyField('WorkflowActionClass', $typeLabel, $this->singular_name()));
201
		$titleField = new TextField('Title', $this->fieldLabel('Title'));
202
		$titleField->setDescription(_t(
203
			'WorkflowAction.TitleDescription',
204
			'The Title is used as the button label for this Workflow Action'
205
		));
206
		$fields->addFieldToTab('Root.Main', $titleField);
207
		$fields->addFieldToTab('Root.Main', new DropdownField('AllowEditing', $this->fieldLabel('AllowEditing'),
208
			array(
209
				'By Assignees' => _t('AllowEditing.ByAssignees', 'By Assignees'),
210
				'Content Settings' => _t('AllowEditing.ContentSettings', 'Content Settings'),
211
				'No' => _t('AllowEditing.NoString', 'No')
212
			),
213
		 	_t('AllowEditing.NoString', 'No')
214
		));
215
		$fields->addFieldToTab('Root.Main', new CheckboxField('AllowCommenting', $this->fieldLabel('AllowCommenting'),$this->AllowCommenting));
216
		$this->extend('updateCMSFields', $fields);
217
		return $fields;
218
	}
219
220
	public function getValidator() {
221
		return new RequiredFields('Title');
222
	}
223
224
	public function summaryFields() {
225
		return array(
226
			'Title' => $this->fieldLabel('Title'),
227
			'Transitions' => $this->fieldLabel('Transitions'),
228
		);
229
	}
230
231
	public function fieldLabels($includerelations = true) {
232
		$labels = parent::fieldLabels($includerelations);
233
		$labels['Comment'] = _t('WorkflowAction.CommentLabel', 'Comment');
234
		$labels['Type'] = _t('WorkflowAction.TypeLabel', 'Type');
235
		$labels['Executed'] = _t('WorkflowAction.ExecutedLabel', 'Executed');
236
		$labels['AllowEditing'] = _t('WorkflowAction.ALLOW_EDITING', 'Allow editing during this step?');
237
		$labels['Title'] = _t('WorkflowAction.TITLE', 'Title');
238
		$labels['AllowCommenting'] = _t('WorkflowAction.ALLOW_COMMENTING','Allow Commenting?');
239
		$labels['Transitions'] = _t('WorkflowAction.Transitions','Transitions');
240
241
		return $labels;
242
	}
243
244
	/**
245
	 * Used for Front End Workflows
246
	 */
247
	public function updateFrontendWorkflowFields($fields, $workflow){
248
249
	}
250
251
252
	public function Icon() {
253
		return $this->stat('icon');
254
	}
255
}