Passed
Push — develop ( 4abc61...39fefa )
by Jens
03:39
created

FormComponent::isFormSubmitted()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 5
eloc 2
c 2
b 0
f 1
nc 5
nop 1
dl 0
loc 4
rs 8.8571
1
<?php
2
namespace library\components;
3
4
5
use library\cc\Application;
6
use library\storage\Storage;
7
use library\storage\Storage;
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Cannot use library\storage\Storage as Storage because the name is already in use
Loading history...
8
9
class FormComponent Extends BaseComponent
10
{
11
	const GET_PARAMETER_PATH = 'path';
12
13
	const PARAMETER_CMS_PREFIX = 'cmsPrefix';
14
	const PARAMETER_DOCUMENT_TYPE = 'documentType';
15
	const PARAMETER_DOCUMENT_TYPES = 'documentTypes';
16
	const PARAMETER_FORM_ID = 'formId';
17
	const PARAMETER_FORM_PARAMETER_NAME = 'formParameterName';
18
	const PARAMETER_HIDE_TITLE_AND_STATE = 'hideTitleAndState';
19
	const PARAMETER_RESPONSE_FOLDER = 'responseFolder';
20
	const PARAMETER_SMALLEST_IMAGE = 'smallestImage';
21
	const PARAMETER_SUBMIT_ONCE_PER_SESSION = 'submitOncePerSession';
22
	const PARAMETER_SUB_TEMPLATE = 'subTemplate';
23
	const PARAMETER_THANK_YOU_MESSAGE = 'thankYouMessage';
24
25
	const SESSION_PARAMETER_CLOUDCONTROL = 'cloudcontrol';
26
	const SESSION_PARAMETER_FORM_COMPONENT = 'FormComponent';
27
	/**
28
	 * @var null|string
29
	 */
30
	protected $documentType = null;
31
	/**
32
	 * @var null|string
33
	 */
34
	protected $responseFolder = null;
35
	/**
36
	 * @var string
37
	 */
38
	protected $subTemplate = 'cms/documents/document-form-form';
39
	/**
40
	 * @var string
41
	 */
42
	protected $formParameterName = 'form';
43
	/**
44
	 * @var string
45
	 */
46
	protected $thankYouMessage = 'Thank you for sending us your response.';
47
48
	/**
49
	 * @var bool
50
	 */
51
	protected $submitOncePerSession = false;
52
53
	/**
54
	 * @var string
55
	 */
56
	private $formId;
57
	/**
58
	 * @var null|string
59
	 */
60
	private $getPathBackup = null;
61
62
	/**
63
	 * @var null|\stdClass
64
	 */
65
	private $userSessionBackup = null;
66
67
	/**
68
	 * @param Storage $storage
69
	 *
70
	 * @return void
71
	 * @throws \Exception
72
	 */
73
	public function run(Storage $storage)
74
	{
75
		parent::run($storage);
76
		$this->checkParameters();
77
		$this->checkRequiredParameters();
78
		$this->setFormId();
79
		$this->initialize($storage);
80
		$this->checkSubmit($storage);
81
	}
82
83
	/**
84
	 * @param null|Application $application
85
	 *
86
	 * @throws \Exception
87
	 */
88
	public function render($application = null)
89
	{
90
		$request = $this->setPathBackup();
91
		$form = $this->renderTemplate($this->subTemplate);
92
		$this->resetPathBackup($request);
93
		$this->setFormParameter($form);
94
95
		parent::render($application);
96
	}
97
98
	/**
99
	 * Checks if parameters were given in the CMS configuration and
100
	 * sets them to their respective fields
101
	 */
102
	private function checkParameters()
103
	{
104
		$this->checkDocumentTypeParameter();
105
		$this->checkResponseFolderParameter();
106
		$this->checkSubTemplateParameter();
107
		$this->checkFormParameterNameParameter();
108
		$this->checkThankYouMessageParameter();
109
		$this->checkSubmitOncePerSessionParameter();
110
	}
111
112
	/**
113
	 * Sets variables needed for rendering the form template
114
	 *
115
	 * @param Storage $storage
116
	 */
117
	private function initialize($storage)
118
	{
119
		$this->parameters[self::PARAMETER_SMALLEST_IMAGE] = $storage->getSmallestImageSet()->slug;
120
		$this->parameters[self::PARAMETER_CMS_PREFIX] = '';
121
122
		$this->parameters[self::PARAMETER_DOCUMENT_TYPE] = $this->storage->getDocumentTypeBySlug($this->documentType, true);
123
		$this->parameters[self::PARAMETER_DOCUMENT_TYPES] = $this->storage->getDocumentTypes();
124
		$this->parameters[self::PARAMETER_HIDE_TITLE_AND_STATE] = true;
125
		$this->parameters[self::PARAMETER_FORM_ID] = $this->formId;
126
	}
127
128
	/**
129
	 * If the form has been submitted, save the document
130
	 * Calls $this->postSubmit() afterwards
131
	 *
132
	 * @param Storage $storage
133
	 */
134
	private function checkSubmit($storage)
135
	{
136
		if ($this->isFormSubmitted($this->request) && $this->isSubmitAllowed()) {
137
			$postValues = $this->getPostValues($this->request);
138
			$this->setUserSessionBackup();
139
			$storage->addDocument($postValues);
140
			$this->restoreUserSessionBackup();
141
			$this->setSubmitToSession();
142
			$this->postSubmit($postValues, $storage);
143
		}
144
	}
145
146
	/**
147
	 * Hook for derived classes to take actions after
148
	 * submitting the form
149
	 *
150
	 * @param $postValues
151
	 * @param $storage
152
	 */
153
	protected function postSubmit($postValues, $storage)
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 \library\cc\Request $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
	 * @param \library\cc\Request $request
185
	 * @return array
186
	 */
187
	private function getPostValues($request)
188
	{
189
		$postValues = $request::$post;
190
		$postValues[self::PARAMETER_DOCUMENT_TYPE] = $this->documentType;
191
		$postValues[self::GET_PARAMETER_PATH] = $this->responseFolder;
192
		$postValues['title'] = date('r') . ' - From: ' . $request::$requestUri;
193
194
		return $postValues;
195
	}
196
197
	/**
198
	 * Temporarily stores the current user session in a backup variable
199
	 * and sets a fake user instead
200
	 */
201
	private function setUserSessionBackup()
202
	{
203
		$this->userSessionBackup = isset($_SESSION[self::SESSION_PARAMETER_CLOUDCONTROL]) ? $_SESSION[self::SESSION_PARAMETER_CLOUDCONTROL] : null;
204
		$fakeUser = new \stdClass();
205
		$fakeUser->username = self::SESSION_PARAMETER_FORM_COMPONENT;
206
		$_SESSION[self::SESSION_PARAMETER_CLOUDCONTROL] = $fakeUser;
207
	}
208
209
	/**
210
	 * Removes the fake user and restores the existing user
211
	 * session if it was there
212
	 */
213
	private function restoreUserSessionBackup()
214
	{
215
		if ($this->userSessionBackup === null) {
216
			unset($_SESSION[self::SESSION_PARAMETER_CLOUDCONTROL]);
217
		} else {
218
			$_SESSION[self::SESSION_PARAMETER_CLOUDCONTROL] = $this->userSessionBackup;
219
		}
220
	}
221
222
	private function setSubmitToSession()
223
	{
224
		$_SESSION[self::SESSION_PARAMETER_FORM_COMPONENT][$this->formParameterName]['submitted'] = true;
225
	}
226
227
	private function isSubmitAllowed()
228
	{
229
		if ($this->submitOncePerSession === true && $_SESSION[self::SESSION_PARAMETER_FORM_COMPONENT][$this->formParameterName]['submitted'] === true) {
230
			return false;
231
		} else {
232
			return true;
233
		}
234
	}
235
236
	private function checkDocumentTypeParameter()
237
	{
238
		if (isset($this->parameters[self::PARAMETER_DOCUMENT_TYPE])) {
239
			$this->documentType = $this->parameters[self::PARAMETER_DOCUMENT_TYPE];
240
			unset($this->parameters[self::PARAMETER_DOCUMENT_TYPE]);
241
		}
242
	}
243
244
	private function checkResponseFolderParameter()
245
	{
246
		if (isset($this->parameters[self::PARAMETER_RESPONSE_FOLDER])) {
247
			$this->responseFolder = $this->parameters[self::PARAMETER_RESPONSE_FOLDER];
248
			unset($this->parameters[self::PARAMETER_RESPONSE_FOLDER]);
249
		}
250
	}
251
252
	private function checkSubTemplateParameter()
253
	{
254
		if (isset($this->parameters[self::PARAMETER_SUB_TEMPLATE])) {
255
			$this->subTemplate = $this->parameters[self::PARAMETER_SUB_TEMPLATE];
256
			unset($this->parameters[self::PARAMETER_SUB_TEMPLATE]);
257
		}
258
	}
259
260
	private function checkFormParameterNameParameter()
261
	{
262
		if (isset($this->parameters[self::PARAMETER_FORM_PARAMETER_NAME])) {
263
			$this->formParameterName = $this->parameters[self::PARAMETER_FORM_PARAMETER_NAME];
264
			unset($this->parameters[self::PARAMETER_FORM_PARAMETER_NAME]);
265
		}
266
	}
267
268
	private function checkThankYouMessageParameter()
269
	{
270
		if (isset($this->parameters[self::PARAMETER_THANK_YOU_MESSAGE])) {
271
			$this->thankYouMessage = $this->parameters[self::PARAMETER_THANK_YOU_MESSAGE];
272
			unset($this->parameters[self::PARAMETER_THANK_YOU_MESSAGE]);
273
		}
274
	}
275
276
	private function checkSubmitOncePerSessionParameter()
277
	{
278
		if (isset($this->parameters[self::PARAMETER_SUBMIT_ONCE_PER_SESSION])) {
279
			$this->submitOncePerSession = $this->parameters[self::PARAMETER_SUBMIT_ONCE_PER_SESSION] === 'true';
280
			unset($this->parameters[self::PARAMETER_SUBMIT_ONCE_PER_SESSION]);
281
		}
282
	}
283
284
	/**
285
	 * @throws \Exception
286
	 */
287
	private function checkRequiredParameters()
288
	{
289
		if ($this->documentType === null || $this->responseFolder === null) {
290
			throw new \Exception('Parameters `documentType` and `responseFolder` are required for usage with this form');
291
		}
292
	}
293
294
	/**
295
	 * @return \library\cc\Request
296
	 */
297
	private function setPathBackup()
298
	{
299
		$request = $this->request;
300
		if (isset($request::$get[self::GET_PARAMETER_PATH])) {
301
			$this->getPathBackup = $request::$get[self::GET_PARAMETER_PATH];
302
		}
303
		$request::$get[self::GET_PARAMETER_PATH] = $this->responseFolder;
304
305
		return $request;
306
	}
307
308
	/**
309
	 * @param \library\cc\Request $request
310
	 */
311
	private function resetPathBackup($request)
312
	{
313
		if ($this->getPathBackup !== null) {
314
			$request::$get[self::GET_PARAMETER_PATH] = $this->getPathBackup;
315
		} else {
316
			unset($request::$get[self::GET_PARAMETER_PATH]);
317
		}
318
	}
319
320
	/**
321
	 * @param $form
322
	 */
323
	private function setFormParameter($form)
324
	{
325
		if ($this->isFormSubmitted($this->request) || $this->isSubmitAllowed() === false) {
326
			$this->parameters[$this->formParameterName] = '<a name="' . $this->formId . '"></a>' . $this->thankYouMessage;
327
		} else {
328
			$this->parameters[$this->formParameterName] = $form;
329
		}
330
	}
331
}