Passed
Push — develop ( 6fc664...92a637 )
by Jens
08:36
created

FormComponent::setFormParameter()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 8
rs 9.4285
1
<?php
2
namespace library\components;
3
4
5
use library\cc\Application;
6
use library\storage\Storage;
7
8
class FormComponent Extends BaseComponent
9
{
10
	const GET_PARAMETER_PATH = 'path';
11
12
	const PARAMETER_CMS_PREFIX = 'cmsPrefix';
13
	const PARAMETER_DOCUMENT_TYPE = 'documentType';
14
	const PARAMETER_DOCUMENT_TYPES = 'documentTypes';
15
	const PARAMETER_FORM_ID = 'formId';
16
	const PARAMETER_FORM_PARAMETER_NAME = 'formParameterName';
17
	const PARAMETER_HIDE_TITLE_AND_STATE = 'hideTitleAndState';
18
	const PARAMETER_RESPONSE_FOLDER = 'responseFolder';
19
	const PARAMETER_SMALLEST_IMAGE = 'smallestImage';
20
	const PARAMETER_SUBMIT_ONCE_PER_SESSION = 'submitOncePerSession';
21
	const PARAMETER_SUB_TEMPLATE = 'subTemplate';
22
	const PARAMETER_THANK_YOU_MESSAGE = 'thankYouMessage';
23
24
	const SESSION_PARAMETER_CLOUDCONTROL = 'cloudcontrol';
25
	const SESSION_PARAMETER_FORM_COMPONENT = 'FormComponent';
26
	/**
27
	 * @var null|string
28
	 */
29
	protected $documentType = null;
30
	/**
31
	 * @var null|string
32
	 */
33
	protected $responseFolder = null;
34
	/**
35
	 * @var string
36
	 */
37
	protected $subTemplate = 'cms/documents/document-form-form';
38
	/**
39
	 * @var string
40
	 */
41
	protected $formParameterName = 'form';
42
	/**
43
	 * @var string
44
	 */
45
	protected $thankYouMessage = 'Thank you for sending us your response.';
46
47
	/**
48
	 * @var bool
49
	 */
50
	protected $submitOncePerSession = false;
51
52
	/**
53
	 * @var string
54
	 */
55
	private $formId;
56
	/**
57
	 * @var null|string
58
	 */
59
	private $getPathBackup = null;
60
61
	/**
62
	 * @var null|\stdClass
63
	 */
64
	private $userSessionBackup = null;
65
66
	/**
67
	 * @param Storage $storage
68
	 *
69
	 * @return void
70
	 * @throws \Exception
71
	 */
72
	public function run(Storage $storage)
73
	{
74
		parent::run($storage);
75
		$this->checkParameters();
76
		$this->checkRequiredParameters();
77
		$this->setFormId();
78
		$this->initialize($storage);
79
		$this->checkSubmit($storage);
80
	}
81
82
	/**
83
	 * @param null|Application $application
84
	 *
85
	 * @throws \Exception
86
	 */
87
	public function render($application = null)
88
	{
89
		$request = $this->setPathBackup($get);
0 ignored issues
show
Bug introduced by
The variable $get does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Unused Code introduced by
The call to FormComponent::setPathBackup() has too many arguments starting with $get.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
90
		$form = $this->renderTemplate($this->subTemplate);
91
		$this->resetPathBackup($get, $request);
92
		$this->setFormParameter($form);
93
94
		parent::render($application);
95
	}
96
97
	/**
98
	 * Checks if parameters were given in the CMS configuration and
99
	 * sets them to their respective fields
100
	 */
101
	private function checkParameters()
102
	{
103
		$this->checkDocumentTypeParameter();
104
		$this->checkResponseFolderParameter();
105
		$this->checkSubTemplateParameter();
106
		$this->checkFormParameterNameParameter();
107
		$this->checkThankYouMessageParameter();
108
		$this->checkSubmitOncePerSessionParameter();
109
	}
110
111
	/**
112
	 * Sets variables needed for rendering the form template
113
	 *
114
	 * @param $storage
115
	 */
116
	private function initialize($storage)
117
	{
118
		$this->parameters[self::PARAMETER_SMALLEST_IMAGE] = $storage->getSmallestImageSet()->slug;
119
		$this->parameters[self::PARAMETER_CMS_PREFIX] = '';
120
121
		$this->parameters[self::PARAMETER_DOCUMENT_TYPE] = $this->storage->getDocumentTypeBySlug($this->documentType, true);
122
		$this->parameters[self::PARAMETER_DOCUMENT_TYPES] = $this->storage->getDocumentTypes();
123
		$this->parameters[self::PARAMETER_HIDE_TITLE_AND_STATE] = true;
124
		$this->parameters[self::PARAMETER_FORM_ID] = $this->formId;
125
	}
126
127
	/**
128
	 * If the form has been submitted, save the document
129
	 * Calls $this->postSubmit() afterwards
130
	 *
131
	 * @param Storage $storage
132
	 */
133
	private function checkSubmit($storage)
134
	{
135
		if ($this->isFormSubmitted($this->request) && $this->isSubmitAllowed()) {
136
			$postValues = $this->getPostValues($this->request);
137
			$this->setUserSessionBackup();
138
			$storage->addDocument($postValues);
139
			$this->restoreUserSessionBackup();
140
			$this->setSubmitToSession();
141
			$this->postSubmit($postValues, $storage);
142
		}
143
	}
144
145
	/**
146
	 * Hook for derived classes to take actions after
147
	 * submitting the form
148
	 *
149
	 * @param $postValues
150
	 * @param $storage
151
	 */
152
	protected function postSubmit($postValues, $storage)
0 ignored issues
show
Unused Code introduced by
The parameter $postValues is not used and could be removed.

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

Loading history...
Unused Code introduced by
The parameter $storage is not used and could be removed.

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

Loading history...
153
	{
154
	}
155
156
	/**
157
	 * Sets a unique id for this particular form, so it can recognize
158
	 * it when a submit occurs
159
	 */
160
	private function setFormId()
161
	{
162
		if (isset($_SESSION[self::SESSION_PARAMETER_FORM_COMPONENT][$this->formParameterName][self::PARAMETER_FORM_ID])) {
163
			$this->formId = $_SESSION[self::SESSION_PARAMETER_FORM_COMPONENT][$this->formParameterName][self::PARAMETER_FORM_ID];
164
		} else {
165
			$_SESSION[self::SESSION_PARAMETER_FORM_COMPONENT][$this->formParameterName][self::PARAMETER_FORM_ID] = (string)microtime(true);
166
			$_SESSION[self::SESSION_PARAMETER_FORM_COMPONENT][$this->formParameterName]['submitted'] = false;
167
			$this->formId = $_SESSION[self::SESSION_PARAMETER_FORM_COMPONENT][$this->formParameterName][self::PARAMETER_FORM_ID];
168
		}
169
	}
170
171
	/**
172
	 * Checks if this form has been submitted
173
	 *
174
	 * @param $request
175
	 *
176
	 * @return bool
177
	 */
178
	private function isFormSubmitted($request)
179
	{
180
		return !empty($request::$post) && isset($request::$post[self::PARAMETER_FORM_ID]) && $request::$post[self::PARAMETER_FORM_ID] === $this->formId && isset($_SESSION[self::SESSION_PARAMETER_FORM_COMPONENT][$this->formParameterName][self::PARAMETER_FORM_ID]) && $_SESSION[self::SESSION_PARAMETER_FORM_COMPONENT][$this->formParameterName][self::PARAMETER_FORM_ID] === $this->formId;
181
	}
182
183
	/**
184
	 *
185
	 *
186
	 * @param $request
187
	 */
188
	private function getPostValues($request)
189
	{
190
		$postValues = $request::$post;
191
		$postValues[self::PARAMETER_DOCUMENT_TYPE] = $this->documentType;
192
		$postValues[self::GET_PARAMETER_PATH] = $this->responseFolder;
193
		$postValues['title'] = date('r') . ' - From: ' . $request::$requestUri;
194
195
		return $postValues;
196
	}
197
198
	/**
199
	 * Temporarily stores the current user session in a backup variable
200
	 * and sets a fake user instead
201
	 */
202
	private function setUserSessionBackup()
203
	{
204
		$this->userSessionBackup = isset($_SESSION[self::SESSION_PARAMETER_CLOUDCONTROL]) ? $_SESSION[self::SESSION_PARAMETER_CLOUDCONTROL] : null;
205
		$fakeUser = new \stdClass();
206
		$fakeUser->username = self::SESSION_PARAMETER_FORM_COMPONENT;
207
		$_SESSION[self::SESSION_PARAMETER_CLOUDCONTROL] = $fakeUser;
208
	}
209
210
	/**
211
	 * Removes the fake user and restores the existing user
212
	 * session if it was there
213
	 */
214
	private function restoreUserSessionBackup()
215
	{
216
		if ($this->userSessionBackup === null) {
217
			unset($_SESSION[self::SESSION_PARAMETER_CLOUDCONTROL]);
218
		} else {
219
			$_SESSION[self::SESSION_PARAMETER_CLOUDCONTROL] = $this->userSessionBackup;
220
		}
221
	}
222
223
	private function setSubmitToSession()
224
	{
225
		$_SESSION[self::SESSION_PARAMETER_FORM_COMPONENT][$this->formParameterName]['submitted'] = true;
226
	}
227
228
	private function isSubmitAllowed()
229
	{
230
		if ($this->submitOncePerSession === true && $_SESSION[self::SESSION_PARAMETER_FORM_COMPONENT][$this->formParameterName]['submitted'] === true) {
231
			return false;
232
		} else {
233
			return true;
234
		}
235
	}
236
237 View Code Duplication
	private function checkDocumentTypeParameter()
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...
238
	{
239
		if (isset($this->parameters[self::PARAMETER_DOCUMENT_TYPE])) {
240
			$this->documentType = $this->parameters[self::PARAMETER_DOCUMENT_TYPE];
241
			unset($this->parameters[self::PARAMETER_DOCUMENT_TYPE]);
242
		}
243
	}
244
245 View Code Duplication
	private function checkResponseFolderParameter()
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...
246
	{
247
		if (isset($this->parameters[self::PARAMETER_RESPONSE_FOLDER])) {
248
			$this->responseFolder = $this->parameters[self::PARAMETER_RESPONSE_FOLDER];
249
			unset($this->parameters[self::PARAMETER_RESPONSE_FOLDER]);
250
		}
251
	}
252
253 View Code Duplication
	private function checkSubTemplateParameter()
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...
254
	{
255
		if (isset($this->parameters[self::PARAMETER_SUB_TEMPLATE])) {
256
			$this->subTemplate = $this->parameters[self::PARAMETER_SUB_TEMPLATE];
257
			unset($this->parameters[self::PARAMETER_SUB_TEMPLATE]);
258
		}
259
	}
260
261 View Code Duplication
	private function checkFormParameterNameParameter()
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...
262
	{
263
		if (isset($this->parameters[self::PARAMETER_FORM_PARAMETER_NAME])) {
264
			$this->formParameterName = $this->parameters[self::PARAMETER_FORM_PARAMETER_NAME];
265
			unset($this->parameters[self::PARAMETER_FORM_PARAMETER_NAME]);
266
		}
267
	}
268
269 View Code Duplication
	private function checkThankYouMessageParameter()
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...
270
	{
271
		if (isset($this->parameters[self::PARAMETER_THANK_YOU_MESSAGE])) {
272
			$this->thankYouMessage = $this->parameters[self::PARAMETER_THANK_YOU_MESSAGE];
273
			unset($this->parameters[self::PARAMETER_THANK_YOU_MESSAGE]);
274
		}
275
	}
276
277 View Code Duplication
	private function checkSubmitOncePerSessionParameter()
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...
278
	{
279
		if (isset($this->parameters[self::PARAMETER_SUBMIT_ONCE_PER_SESSION])) {
280
			$this->submitOncePerSession = $this->parameters[self::PARAMETER_SUBMIT_ONCE_PER_SESSION] === 'true';
281
			unset($this->parameters[self::PARAMETER_SUBMIT_ONCE_PER_SESSION]);
282
		}
283
	}
284
285
	/**
286
	 * @throws \Exception
287
	 */
288
	private function checkRequiredParameters()
289
	{
290
		if ($this->documentType === null || $this->responseFolder === null) {
291
			throw new \Exception('Parameters `documentType` and `responseFolder` are required for usage with this form');
292
		}
293
	}
294
295
	/**
296
	 * @return \library\cc\Request
297
	 */
298
	private function setPathBackup()
299
	{
300
		$request = $this->request;
301
		if (isset($request::$get[self::GET_PARAMETER_PATH])) {
302
			$this->getPathBackup = $request::$get[self::GET_PARAMETER_PATH];
303
		}
304
		$request::$get[self::GET_PARAMETER_PATH] = $this->responseFolder;
305
306
		return $request;
307
	}
308
309
	/**
310
	 * @param $get
311
	 * @param $request
312
	 */
313
	private function resetPathBackup($get, $request)
0 ignored issues
show
Unused Code introduced by
The parameter $get is not used and could be removed.

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

Loading history...
314
	{
315
		if ($this->getPathBackup !== null) {
316
			$request::$get[self::GET_PARAMETER_PATH] = $this->getPathBackup;
317
		} else {
318
			unset($request::$get[self::GET_PARAMETER_PATH]);
319
		}
320
	}
321
322
	/**
323
	 * @param $form
324
	 */
325
	private function setFormParameter($form)
326
	{
327
		if ($this->isFormSubmitted($this->request) || $this->isSubmitAllowed() === false) {
328
			$this->parameters[$this->formParameterName] = '<a name="' . $this->formId . '"></a>' . $this->thankYouMessage;
329
		} else {
330
			$this->parameters[$this->formParameterName] = $form;
331
		}
332
	}
333
}