Browse code

Some 3.5.x optimizations and bugfixes

Benjamin Roth authored on05/10/2016 11:48:38
Showing7 changed files
... ...
@@ -1,2 +1,7 @@
1
-order deny,allow
2
-allow from all
3 1
\ No newline at end of file
2
+<IfModule !mod_authz_core.c>
3
+  Order allow,deny
4
+  Allow from all
5
+</IfModule>
6
+<IfModule mod_authz_core.c>
7
+  Require all granted
8
+</IfModule>
4 9
\ No newline at end of file
... ...
@@ -38,7 +38,7 @@ input[type="number"],input[type="search"],input[type="tel"],input[type="time"],i
38 38
 	font-size: 123%;
39 39
 	line-height: 2;
40 40
 	font-weight: normal;
41
-	border: none;
41
+	border-bottom: inherit 3px solid;
42 42
 	margin-bottom: 1em;
43 43
 }
44 44
 
... ...
@@ -143,7 +143,6 @@ input[type="number"],input[type="search"],input[type="tel"],input[type="time"],i
143 143
 	min-height: 2.1em;
144 144
 }
145 145
 
146
-.widget.w5  { float: left; width: 3%; }
147 146
 .widget.w10 { float: left; width: 8%; }
148 147
 .widget.w15 { float: left; width: 13%; }
149 148
 .widget.w20 { float: left; width: 18%; }
... ...
@@ -171,7 +170,6 @@ input[type="number"],input[type="search"],input[type="tel"],input[type="time"],i
171 170
 }
172 171
 
173 172
 @media screen and (max-width: 43em) {
174
-	.widget.w5,
175 173
 	.widget.w10,
176 174
 	.widget.w15,
177 175
 	.widget.w20,
... ...
@@ -193,8 +191,6 @@ input[type="number"],input[type="search"],input[type="tel"],input[type="time"],i
193 191
 	.widget.w100 { float: none; width: 98%; }
194 192
 }
195 193
 
196
-.widget.w5:before,
197
-.widget.w5:after,
198 194
 .widget.w10:before,
199 195
 .widget.w10:after,
200 196
 .widget.w15:before,
... ...
@@ -239,7 +235,6 @@ form:after {
239 235
 	display: table; /* 2 */
240 236
 }
241 237
 
242
-.widget.w5:after,
243 238
 .widget.w10:after,
244 239
 .widget.w15:after,
245 240
 .widget.w20:after,
... ...
@@ -1 +1 @@
1
-input[type="text"],input[type="password"],input[type="date"],input[type="datetime"],input[type="email"],input[type="number"],input[type="search"],input[type="tel"],input[type="time"],input[type="url"],textarea,select{width:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.widget input.captcha{max-width:4em}.formbody>fieldset{clear:left}.formbody>fieldset legend{color:inherit;font-size:123%;line-height:2;font-weight:normal;border:0;margin-bottom:1em}.widget .radio_container legend,.widget .checkbox_container legend{color:inherit;font-size:100%;font-weight:normal;border-bottom:0;display:block;margin-bottom:.4em;line-height:1.5em}.widget .checkbox_container label,.widget .radio_container label{font-weight:normal;display:inline;margin-bottom:0}.widget .checkbox_container>span,.widget .radio_container>span{display:block}.widget.headline{margin-top:1em;font-size:108%;font-weight:bold;min-height:1.5em}.widget{padding:0 1%;margin-bottom:.5em;min-height:4em;float:left;width:98%}.widget.cbx{min-height:1.5em;height:1.5em;padding:4px 1%}.widget label{display:block;margin-bottom:.4em;line-height:1.5em}.widget.error input,.widget.error select,.widget.error textarea{border-color:#e23e15}.widget p.error{font-size:85%;margin-top:-0.4em;margin-bottom:.4em}.widget.error .errortip{background-color:#e23e15;border-bottom-left-radius:50%;border-bottom-right-radius:50%;border-top-left-radius:50%;border-top-right-radius:50%;color:#fff;cursor:help;display:block;float:right;font-family:'Open Sans',Arial,Helvetica,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;height:15px;line-height:13px;margin-top:3.25px;text-align:center;vertical-align:top;width:15px}.submit_container{min-height:2.1em}.widget.w5{float:left;width:3%}.widget.w10{float:left;width:8%}.widget.w15{float:left;width:13%}.widget.w20{float:left;width:18%}.widget.w25{float:left;width:23%}.widget.w30{float:left;width:28%}.widget.w35{float:left;width:33%}.widget.w40{float:left;width:38%}.widget.w45{float:left;width:43%}.widget.w50{float:left;width:48%}.widget.w55{float:left;width:53%}.widget.w60{float:left;width:58%}.widget.w65{float:left;width:63%}.widget.w70{float:left;width:68%}.widget.w75{float:left;width:73%}.widget.w80{float:left;width:78%}.widget.w85{float:left;width:83%}.widget.w90{float:left;width:88%}.widget.w95{float:left;width:93%}.widget.w100{float:left;width:98%}.widget.clr,.formbody>fieldset{clear:left}@media screen and (max-width:43em){.widget.w5,.widget.w10,.widget.w15,.widget.w20,.widget.w25,.widget.w30,.widget.w35,.widget.w40,.widget.w45,.widget.w50,.widget.w55,.widget.w60,.widget.w65,.widget.w70,.widget.w75,.widget.w80,.widget.w85,.widget.w90,.widget.w95,.widget.w100{float:none;width:98%}}.widget.w5:before,.widget.w5:after,.widget.w10:before,.widget.w10:after,.widget.w15:before,.widget.w15:after,.widget.w20:before,.widget.w20:after,.widget.w25:before,.widget.w25:after,.widget.w30:before,.widget.w30:after,.widget.w35:before,.widget.w35:after,.widget.w40:before,.widget.w40:after,.widget.w45:before,.widget.w45:after,.widget.w50:before,.widget.w50:after,.widget.w55:before,.widget.w55:after,.widget.w60:before,.widget.w60:after,.widget.w65:before,.widget.w65:after,.widget.w70:before,.widget.w70:after,.widget.w75:before,.widget.w75:after,.widget.w80:before,.widget.w80:after,.widget.w85:before,.widget.w85:after,.widget.w90:before,.widget.w90:after,.widget.w95:before,.widget.w95:after,.widget.w100:before,.widget.w100:after,form:before,form:after{content:" ";display:table}.widget.w5:after,.widget.w10:after,.widget.w15:after,.widget.w20:after,.widget.w25:after,.widget.w30:after,.widget.w35:after,.widget.w40:after,.widget.w45:after,.widget.w50:after,.widget.w55:after,.widget.w60:after,.widget.w65:after,.widget.w70:after,.widget.w75:after,.widget.w80:after,.widget.w85:after,.widget.w90:after,.widget.w95:after,.widget.w100:after,form:after{clear:both}.widget.widget-split input[type="text"],.widget.widget-split input[type="password"],.widget.widget-split input[type="date"],.widget.widget-split input[type="datetime"],.widget.widget-split input[type="email"],.widget.widget-split input[type="number"],.widget.widget-split input[type="search"],.widget.widget-split input[type="tel"],.widget.widget-split input[type="time"],.widget.widget-split input[type="url"],.widget.widget-split textarea,.widget.widget-split select{max-width:50%!important;min-width:10%!important;float:left;margin-right:10px;display:inline}.widget.widget-split.widget-split-3 input{max-width:30%!important}.widget.widget-split.widget-split-3 input[type="submit"]{max-width:70%!important}.widget.widget-split.widget-split-4 input{max-width:40%!important}.widget.widget-split.widget-split-4 input[type="submit"]{max-width:60%!important}.widget.widget-split.widget-split-5 input{max-width:50%!important}.widget.widget-split.widget-split-5 input[type="submit"]{max-width:50%!important}.widget.widget-split.widget-split-6 input{max-width:60%!important}.widget.widget-split.widget-split-6 input[type="submit"]{max-width:40%!important}.widget.widget-split.widget-split-7 input{max-width:70%!important}.widget.widget-split.widget-split-7 input[type="submit"]{max-width:30%!important}.widget.fl_right input[type="submit"],.submit_container.fl_right .submit{float:right}.widget.lblp{padding-top:1.9em;min-height:2.1em}.widget.autoh{min-height:0}.widget,form{*zoom:1}
2 1
\ No newline at end of file
2
+input[type="text"],input[type="password"],input[type="date"],input[type="datetime"],input[type="email"],input[type="number"],input[type="search"],input[type="tel"],input[type="time"],input[type="url"],textarea,select{width:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.widget input.captcha{max-width:4em}.formbody>fieldset{clear:left}.formbody>fieldset legend{color:inherit;font-size:123%;line-height:2;font-weight:normal;border-bottom:inherit 3px solid;margin-bottom:1em}.widget .radio_container legend,.widget .checkbox_container legend{color:inherit;font-size:100%;font-weight:normal;border-bottom:0;display:block;margin-bottom:.4em;line-height:1.5em}.widget .checkbox_container label,.widget .radio_container label{font-weight:normal;display:inline;margin-bottom:0}.widget .checkbox_container>span,.widget .radio_container>span{display:block}.widget.headline{margin-top:1em;font-size:108%;font-weight:bold;min-height:1.5em}.widget{padding:0 1%;margin-bottom:.5em;min-height:4em;float:left;width:98%}.widget.cbx{min-height:1.5em;height:1.5em;padding:4px 1%}.widget label{display:block;margin-bottom:.4em;line-height:1.5em}.widget.error input,.widget.error select,.widget.error textarea{border-color:#e23e15}.widget p.error{font-size:85%;margin-top:-0.4em;margin-bottom:.4em}.widget.error .errortip{background-color:#e23e15;border-bottom-left-radius:50%;border-bottom-right-radius:50%;border-top-left-radius:50%;border-top-right-radius:50%;color:#fff;cursor:help;display:block;float:right;font-family:'Open Sans',Arial,Helvetica,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;height:15px;line-height:13px;margin-top:3.25px;text-align:center;vertical-align:top;width:15px}.submit_container{min-height:2.1em}.widget.w10{float:left;width:8%}.widget.w15{float:left;width:13%}.widget.w20{float:left;width:18%}.widget.w25{float:left;width:23%}.widget.w30{float:left;width:28%}.widget.w35{float:left;width:33%}.widget.w40{float:left;width:38%}.widget.w45{float:left;width:43%}.widget.w50{float:left;width:48%}.widget.w55{float:left;width:53%}.widget.w60{float:left;width:58%}.widget.w65{float:left;width:63%}.widget.w70{float:left;width:68%}.widget.w75{float:left;width:73%}.widget.w80{float:left;width:78%}.widget.w85{float:left;width:83%}.widget.w90{float:left;width:88%}.widget.w95{float:left;width:93%}.widget.w100{float:left;width:98%}.widget.clr,.formbody>fieldset{clear:left}@media screen and (max-width:43em){.widget.w10,.widget.w15,.widget.w20,.widget.w25,.widget.w30,.widget.w35,.widget.w40,.widget.w45,.widget.w50,.widget.w55,.widget.w60,.widget.w65,.widget.w70,.widget.w75,.widget.w80,.widget.w85,.widget.w90,.widget.w95,.widget.w100{float:none;width:98%}}.widget.w10:before,.widget.w10:after,.widget.w15:before,.widget.w15:after,.widget.w20:before,.widget.w20:after,.widget.w25:before,.widget.w25:after,.widget.w30:before,.widget.w30:after,.widget.w35:before,.widget.w35:after,.widget.w40:before,.widget.w40:after,.widget.w45:before,.widget.w45:after,.widget.w50:before,.widget.w50:after,.widget.w55:before,.widget.w55:after,.widget.w60:before,.widget.w60:after,.widget.w65:before,.widget.w65:after,.widget.w70:before,.widget.w70:after,.widget.w75:before,.widget.w75:after,.widget.w80:before,.widget.w80:after,.widget.w85:before,.widget.w85:after,.widget.w90:before,.widget.w90:after,.widget.w95:before,.widget.w95:after,.widget.w100:before,.widget.w100:after,form:before,form:after{content:" ";display:table}.widget.w10:after,.widget.w15:after,.widget.w20:after,.widget.w25:after,.widget.w30:after,.widget.w35:after,.widget.w40:after,.widget.w45:after,.widget.w50:after,.widget.w55:after,.widget.w60:after,.widget.w65:after,.widget.w70:after,.widget.w75:after,.widget.w80:after,.widget.w85:after,.widget.w90:after,.widget.w95:after,.widget.w100:after,form:after{clear:both}.widget.widget-split input[type="text"],.widget.widget-split input[type="password"],.widget.widget-split input[type="date"],.widget.widget-split input[type="datetime"],.widget.widget-split input[type="email"],.widget.widget-split input[type="number"],.widget.widget-split input[type="search"],.widget.widget-split input[type="tel"],.widget.widget-split input[type="time"],.widget.widget-split input[type="url"],.widget.widget-split textarea,.widget.widget-split select{max-width:50%!important;min-width:10%!important;float:left;margin-right:10px;display:inline}.widget.widget-split.widget-split-3 input{max-width:30%!important}.widget.widget-split.widget-split-3 input[type="submit"]{max-width:70%!important}.widget.widget-split.widget-split-4 input{max-width:40%!important}.widget.widget-split.widget-split-4 input[type="submit"]{max-width:60%!important}.widget.widget-split.widget-split-5 input{max-width:50%!important}.widget.widget-split.widget-split-5 input[type="submit"]{max-width:50%!important}.widget.widget-split.widget-split-6 input{max-width:60%!important}.widget.widget-split.widget-split-6 input[type="submit"]{max-width:40%!important}.widget.widget-split.widget-split-7 input{max-width:70%!important}.widget.widget-split.widget-split-7 input[type="submit"]{max-width:30%!important}.widget.fl_right input[type="submit"],.submit_container.fl_right .submit{float:right}.widget.lblp{padding-top:1.9em;min-height:2.1em}.widget.autoh{min-height:0}.widget,form{*zoom:1}
3 3
\ No newline at end of file
... ...
@@ -32,7 +32,7 @@ $GLOBALS['TL_DCA']['tl_form_field']['fields']['eSM_fl_width'] = array
32 32
 	'exclude'                 => true,
33 33
 	'inputType'               => 'select',
34 34
 	'default'                 => 100,
35
-	'options'                 => array(5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100),
35
+	'options'                 => array(10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100),
36 36
 	'reference'               => &$GLOBALS['TL_LANG']['tl_form_field']['ref_width'],
37 37
 	'eval'                    => array('tl_class'=>'w50'),
38 38
 	'sql'                     => "varchar(3) NOT NULL default '100'"
... ...
@@ -32,7 +32,6 @@ $GLOBALS['TL_LANG']['tl_form_field']['formilicious_legend']  = 'Formilicious Fra
32 32
  */
33 33
 $GLOBALS['TL_LANG']['tl_form_field']['ref_width']     = array
34 34
 (
35
-	5   => '5 %',
36 35
 	10  => '10 %',
37 36
 	15  => '15 %',
38 37
 	20  => '20 %',
... ...
@@ -31,320 +31,357 @@ class ModulePersonalData extends \Contao\ModulePersonalData
31 31
 {
32 32
 
33 33
 	/**
34
-	 * Generate the module
35
-	 */
36
-	protected function compile()
37
-	{
38
-		global $objPage;
39
-		$this->import('FrontendUser', 'User');
40
-
41
-		$GLOBALS['TL_LANGUAGE'] = $objPage->language;
42
-
43
-		\System::loadLanguageFile('tl_member');
44
-		$this->loadDataContainer('tl_member');
45
-
46
-		// Call onload_callback (e.g. to check permissions)
47
-		if (is_array($GLOBALS['TL_DCA']['tl_member']['config']['onload_callback']))
48
-		{
49
-			foreach ($GLOBALS['TL_DCA']['tl_member']['config']['onload_callback'] as $callback)
50
-			{
51
-				if (is_array($callback))
52
-				{
53
-					$this->import($callback[0]);
54
-					$this->$callback[0]->$callback[1]();
55
-				}
56
-				elseif (is_callable($callback))
57
-				{
58
-					$callback();
59
-				}
60
-			}
61
-		}
62
-
63
-		// Set the template
64
-		if ($this->memberTpl != '')
65
-		{
66
-			$this->Template = new \FrontendTemplate($this->memberTpl);
67
-			$this->Template->setData($this->arrData);
68
-		}
69
-
70
-		$this->Template->fields = '';
71
-		$this->Template->tableless = $this->tableless;
72
-
73
-		$arrFields = array();
74
-		$doNotSubmit = false;
75
-		$hasUpload = false;
76
-		$row = 0;
77
-
78
-		$blnModified = false;
79
-		$objMember = \MemberModel::findByPk($this->User->id);
80
-
81
-		// Build the form
82
-		foreach ($this->editable as $fielddata)
83
-		{
84
-			// Split formilicious editable data in single vars
85
-			list($field,$fieldWidth,$fieldClr,$fieldMandatory) = array_values($fielddata);
86
-			$arrData = &$GLOBALS['TL_DCA']['tl_member']['fields'][$field];
87
-
88
-			// Map checkboxWizards to regular checkbox widgets
89
-			if ($arrData['inputType'] == 'checkboxWizard')
90
-			{
91
-				$arrData['inputType'] = 'checkbox';
92
-			}
93
-
94
-			$strClass = $GLOBALS['TL_FFL'][$arrData['inputType']];
95
-
96
-			// Continue if the class does not exist
97
-			if (!$arrData['eval']['feEditable'] || !class_exists($strClass))
98
-			{
99
-				continue;
100
-			}
101
-
102
-			$strGroup = $arrData['eval']['feGroup'];
103
-
104
-			$arrData['eval']['required'] = false;
105
-			$arrData['eval']['tableless'] = $this->tableless;
106
-
107
-			// Use strlen() here (see #3277)
108
-			if ($arrData['eval']['mandatory'])
109
-			{
110
-				if (is_array($this->User->$field))
111
-				{
112
-					if (empty($this->User->$field))
113
-					{
114
-						$arrData['eval']['required'] = true;
115
-					}
116
-				}
117
-				else
118
-				{
119
-					if (!strlen($this->User->$field))
120
-					{
121
-						$arrData['eval']['required'] = true;
122
-					}
123
-				}
124
-			}
125
-
126
-			$varValue = $this->User->$field;
127
-
128
-			// Call the load_callback
129
-			if (isset($arrData['load_callback']) && is_array($arrData['load_callback']))
130
-			{
131
-				foreach ($arrData['load_callback'] as $callback)
132
-				{
133
-					if (is_array($callback))
134
-					{
135
-						$this->import($callback[0]);
136
-						$varValue = $this->$callback[0]->$callback[1]($varValue, $this->User, $this);
137
-					}
138
-					elseif (is_callable($callback))
139
-					{
140
-						$varValue = $callback($varValue, $this->User, $this);
141
-					}
142
-				}
143
-			}
144
-
145
-			$objWidget = new $strClass($strClass::getAttributesFromDca($arrData, $field, $varValue, '', '', $this));
146
-
147
-			$objWidget->storeValues = true;
148
-			$objWidget->rowClass = 'row_'.$row . (($row == 0) ? ' row_first' : '') . ((($row % 2) == 0) ? ' even' : ' odd');
149
-
150
-			// Extend with formilicious data
151
-			$objWidget->eSM_fl_width = $fieldWidth;
152
-			$objWidget->eSM_fl_clear = $fieldClr;
153
-			if ($fieldMandatory)
154
-			{
155
-				$objWidget->required = $fieldMandatory;
156
-				$objWidget->mandatory = $fieldMandatory;
157
-			} else {
158
-				$objWidget->required = false;
159
-				$objWidget->mandatory = false;
160
-			}
161
-			if (in_array($arrData['eval']['rgxp'], array('date','time','datim')))
162
-			{
163
-				$strDateFormatFunc = 'getNumeric'.ucfirst($arrData['eval']['rgxp']).'Format';
164
-				$objWidget->placeholder = \Date::getInputFormat(\Date::$strDateFormatFunc());
165
-				$objWidget->maxlength = strlen($objWidget->placeholder);
166
-			}
167
-
168
-			// Increase the row count if it is a password field
169
-			if ($objWidget instanceof \FormPassword)
170
-			{
171
-				++$row;
172
-				$objWidget->rowClassConfirm = 'row_'.$row . ((($row % 2) == 0) ? ' even' : ' odd');
173
-			}
174
-
175
-			// Validate the form data
176
-			if (\Input::post('FORM_SUBMIT') == 'tl_member_' . $this->id)
177
-			{
178
-				$objWidget->validate();
179
-				$varValue = $objWidget->value;
180
-
181
-				$rgxp = $arrData['eval']['rgxp'];
182
-
183
-				// Convert date formats into timestamps (check the eval setting first -> #3063)
184
-				if (($rgxp == 'date' || $rgxp == 'time' || $rgxp == 'datim') && $varValue != '')
185
-				{
186
-					try
187
-					{
188
-						$objDate = new \Date($varValue);
189
-						$varValue = $objDate->tstamp;
190
-					}
191
-					catch (\OutOfBoundsException $e)
192
-					{
193
-						$objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidDate'], $varValue));
194
-					}
195
-				}
196
-
197
-				// Make sure that unique fields are unique (check the eval setting first -> #3063)
198
-				if ($arrData['eval']['unique'] && $varValue != '' && !$this->Database->isUniqueValue('tl_member', $field, $varValue, $this->User->id))
199
-				{
200
-					$objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['unique'], $arrData['label'][0] ?: $field));
201
-				}
202
-
203
-				// Trigger the save_callback (see #5247)
204
-				if ($objWidget->submitInput() && !$objWidget->hasErrors() && is_array($arrData['save_callback']))
205
-				{
206
-					foreach ($arrData['save_callback'] as $callback)
207
-					{
208
-						try
209
-						{
210
-							if (is_array($callback))
211
-							{
212
-								$this->import($callback[0]);
213
-								$varValue = $this->$callback[0]->$callback[1]($varValue, $this->User, $this);
214
-							}
215
-							elseif (is_callable($callback))
216
-							{
217
-								$varValue = $callback($varValue, $this->User, $this);
218
-							}
219
-						}
220
-						catch (\Exception $e)
221
-						{
222
-							$objWidget->class = 'error';
223
-							$objWidget->addError($e->getMessage());
224
-						}
225
-					}
226
-				}
227
-
228
-				// Do not submit the field if there are errors
229
-				if ($objWidget->hasErrors())
230
-				{
231
-					$doNotSubmit = true;
232
-				}
233
-				elseif ($objWidget->submitInput())
234
-				{
235
-					// Store the form data
236
-					$_SESSION['FORM_DATA'][$field] = $varValue;
237
-
238
-					// Set the correct empty value (see #6284, #6373)
239
-					if ($varValue === '')
240
-					{
241
-						$varValue = $objWidget->getEmptyValue();
242
-					}
243
-
244
-					// Set the new value
245
-					$this->User->$field = $varValue;
246
-
247
-					// Set the new field in the member model
248
-					$blnModified = true;
249
-					$objMember->$field = $varValue;
250
-				}
251
-			}
252
-
253
-			if ($objWidget instanceof \uploadable)
254
-			{
255
-				$hasUpload = true;
256
-			}
257
-
258
-			$temp = $objWidget->parse();
259
-
260
-			$this->Template->fields .= $temp;
261
-			$arrFields[$strGroup][$field] .= $temp;
262
-			++$row;
263
-		}
264
-
265
-		// Save the model
266
-		if ($blnModified)
267
-		{
268
-			$objMember->save();
269
-		}
270
-
271
-		$this->Template->hasError = $doNotSubmit;
272
-
273
-		// Redirect or reload if there was no error
274
-		if (\Input::post('FORM_SUBMIT') == 'tl_member_' . $this->id && !$doNotSubmit)
275
-		{
276
-			// HOOK: updated personal data
277
-			if (isset($GLOBALS['TL_HOOKS']['updatePersonalData']) && is_array($GLOBALS['TL_HOOKS']['updatePersonalData']))
278
-			{
279
-				foreach ($GLOBALS['TL_HOOKS']['updatePersonalData'] as $callback)
280
-				{
281
-					$this->import($callback[0]);
282
-					$this->$callback[0]->$callback[1]($this->User, $_SESSION['FORM_DATA'], $this);
283
-				}
284
-			}
285
-
286
-			// Call the onsubmit_callback
287
-			if (is_array($GLOBALS['TL_DCA']['tl_member']['config']['onsubmit_callback']))
288
-			{
289
-				foreach ($GLOBALS['TL_DCA']['tl_member']['config']['onsubmit_callback'] as $callback)
290
-				{
291
-					if (is_array($callback))
292
-					{
293
-						$this->import($callback[0]);
294
-						$this->$callback[0]->$callback[1]($this->User, $this);
295
-					}
296
-					elseif (is_callable($callback))
297
-					{
298
-						$callback($this->User, $this);
299
-					}
300
-				}
301
-			}
302
-
303
-			// Check whether there is a jumpTo page
304
-			if (($objJumpTo = $this->objModel->getRelated('jumpTo')) !== null)
305
-			{
306
-				$this->jumpToOrReload($objJumpTo->row());
307
-			}
308
-
309
-			$this->reload();
310
-		}
311
-
312
-		$this->Template->loginDetails = $GLOBALS['TL_LANG']['tl_member']['loginDetails'];
313
-		$this->Template->addressDetails = $GLOBALS['TL_LANG']['tl_member']['addressDetails'];
314
-		$this->Template->contactDetails = $GLOBALS['TL_LANG']['tl_member']['contactDetails'];
315
-		$this->Template->personalData = $GLOBALS['TL_LANG']['tl_member']['personalData'];
316
-
317
-		// Add groups
318
-		foreach ($arrFields as $k=>$v)
319
-		{
320
-			$this->Template->$k = $v;
321
-		}
322
-
323
-		$this->Template->formId = 'tl_member_' . $this->id;
324
-		$this->Template->slabel = specialchars($GLOBALS['TL_LANG']['MSC']['saveData']);
325
-		$this->Template->action = \Environment::get('indexFreeRequest');
326
-		$this->Template->enctype = $hasUpload ? 'multipart/form-data' : 'application/x-www-form-urlencoded';
327
-		$this->Template->rowLast = 'row_' . $row . ((($row % 2) == 0) ? ' even' : ' odd');
328
-
329
-		// HOOK: add memberlist fields
330
-		if (in_array('memberlist', \ModuleLoader::getActive()))
331
-		{
332
-			$this->Template->profile = $arrFields['profile'];
333
-			$this->Template->profileDetails = $GLOBALS['TL_LANG']['tl_member']['profileDetails'];
334
-		}
335
-
336
-		// HOOK: add newsletter fields
337
-		if (in_array('newsletter', \ModuleLoader::getActive()))
338
-		{
339
-			$this->Template->newsletter = $arrFields['newsletter'];
340
-			$this->Template->newsletterDetails = $GLOBALS['TL_LANG']['tl_member']['newsletterDetails'];
341
-		}
342
-
343
-		// HOOK: add helpdesk fields
344
-		if (in_array('helpdesk', \ModuleLoader::getActive()))
345
-		{
346
-			$this->Template->helpdesk = $arrFields['helpdesk'];
347
-			$this->Template->helpdeskDetails = $GLOBALS['TL_LANG']['tl_member']['helpdeskDetails'];
348
-		}
349
-	}
34
+   * Generate the module
35
+   */
36
+  protected function compile()
37
+  {
38
+    /** @var \PageModel $objPage */
39
+    global $objPage;
40
+
41
+    $this->import('FrontendUser', 'User');
42
+
43
+    $GLOBALS['TL_LANGUAGE'] = $objPage->language;
44
+
45
+    \System::loadLanguageFile('tl_member');
46
+    $this->loadDataContainer('tl_member');
47
+
48
+    // Call onload_callback (e.g. to check permissions)
49
+    if (is_array($GLOBALS['TL_DCA']['tl_member']['config']['onload_callback']))
50
+    {
51
+      foreach ($GLOBALS['TL_DCA']['tl_member']['config']['onload_callback'] as $callback)
52
+      {
53
+        if (is_array($callback))
54
+        {
55
+          $this->import($callback[0]);
56
+          $this->{$callback[0]}->{$callback[1]}();
57
+        }
58
+        elseif (is_callable($callback))
59
+        {
60
+          $callback();
61
+        }
62
+      }
63
+    }
64
+
65
+    // Set the template
66
+    if ($this->memberTpl != '')
67
+    {
68
+      /** @var \FrontendTemplate|object $objTemplate */
69
+      $objTemplate = new \FrontendTemplate($this->memberTpl);
70
+
71
+      $this->Template = $objTemplate;
72
+      $this->Template->setData($this->arrData);
73
+    }
74
+
75
+    $this->Template->fields = '';
76
+    $this->Template->tableless = $this->tableless;
77
+
78
+    $arrFields = array();
79
+    $doNotSubmit = false;
80
+    $hasUpload = false;
81
+    $row = 0;
82
+
83
+    // Predefine the group order (other groups will be appended automatically)
84
+    $arrGroups = array
85
+    (
86
+      'personal' => array(),
87
+      'address'  => array(),
88
+      'contact'  => array(),
89
+      'login'    => array(),
90
+      'profile'  => array()
91
+    );
92
+
93
+    $blnModified = false;
94
+    $objMember = \MemberModel::findByPk($this->User->id);
95
+    $strTable = $objMember->getTable();
96
+
97
+    // Initialize the versioning (see #7415)
98
+    $objVersions = new \Versions($strTable, $objMember->id);
99
+    $objVersions->setUsername($objMember->username);
100
+    $objVersions->setUserId(0);
101
+    $objVersions->setEditUrl('contao/main.php?do=member&act=edit&id=%s&rt=1');
102
+    $objVersions->initialize();
103
+
104
+    // Build the form
105
+    foreach ($this->editable as $fielddata)
106
+    {
107
+      // Split formilicious editable data in single vars
108
+      list($field,$fieldWidth,$fieldClr,$fieldMandatory) = array_values($fielddata);
109
+
110
+      $arrData = &$GLOBALS['TL_DCA']['tl_member']['fields'][$field];
111
+
112
+      // Map checkboxWizards to regular checkbox widgets
113
+      if ($arrData['inputType'] == 'checkboxWizard')
114
+      {
115
+        $arrData['inputType'] = 'checkbox';
116
+      }
117
+
118
+      // Map fileTrees to upload widgets (see #8091)
119
+      if ($arrData['inputType'] == 'fileTree')
120
+      {
121
+        $arrData['inputType'] = 'upload';
122
+      }
123
+
124
+      /** @var \Widget $strClass */
125
+      $strClass = $GLOBALS['TL_FFL'][$arrData['inputType']];
126
+
127
+      // Continue if the class does not exist
128
+      if (!$arrData['eval']['feEditable'] || !class_exists($strClass))
129
+      {
130
+        continue;
131
+      }
132
+
133
+      $strGroup = $arrData['eval']['feGroup'];
134
+
135
+      $arrData['eval']['required'] = false;
136
+      $arrData['eval']['tableless'] = $this->tableless;
137
+
138
+      // Use strlen() here (see #3277)
139
+      if ($arrData['eval']['mandatory'])
140
+      {
141
+        if (is_array($this->User->$field))
142
+        {
143
+          if (empty($this->User->$field))
144
+          {
145
+            $arrData['eval']['required'] = true;
146
+          }
147
+        }
148
+        else
149
+        {
150
+          if (!strlen($this->User->$field))
151
+          {
152
+            $arrData['eval']['required'] = true;
153
+          }
154
+        }
155
+      }
156
+
157
+      $varValue = $this->User->$field;
158
+
159
+      // Call the load_callback
160
+      if (isset($arrData['load_callback']) && is_array($arrData['load_callback']))
161
+      {
162
+        foreach ($arrData['load_callback'] as $callback)
163
+        {
164
+          if (is_array($callback))
165
+          {
166
+            $this->import($callback[0]);
167
+            $varValue = $this->{$callback[0]}->{$callback[1]}($varValue, $this->User, $this);
168
+          }
169
+          elseif (is_callable($callback))
170
+          {
171
+            $varValue = $callback($varValue, $this->User, $this);
172
+          }
173
+        }
174
+      }
175
+
176
+      /** @var \Widget $objWidget */
177
+      $objWidget = new $strClass($strClass::getAttributesFromDca($arrData, $field, $varValue, $field, $strTable, $this));
178
+
179
+      $objWidget->storeValues = true;
180
+      $objWidget->rowClass = 'row_' . $row . (($row == 0) ? ' row_first' : '') . ((($row % 2) == 0) ? ' even' : ' odd');
181
+
182
+      // Extend with formilicious data
183
+      $objWidget->eSM_fl_width = $fieldWidth;
184
+      $objWidget->eSM_fl_clear = $fieldClr;
185
+      if ($fieldMandatory)
186
+      {
187
+        $objWidget->required = $fieldMandatory;
188
+        $objWidget->mandatory = $fieldMandatory;
189
+      } else {
190
+        $objWidget->required = false;
191
+        $objWidget->mandatory = false;
192
+      }
193
+      if (in_array($arrData['eval']['rgxp'], array('date','time','datim')))
194
+      {
195
+        $strDateFormatFunc = 'getNumeric'.ucfirst($arrData['eval']['rgxp']).'Format';
196
+        $objWidget->placeholder = \Date::getInputFormat(\Date::$strDateFormatFunc());
197
+        $objWidget->maxlength = strlen($objWidget->placeholder);
198
+      }
199
+
200
+      // Increase the row count if it is a password field
201
+      if ($objWidget instanceof \FormPassword)
202
+      {
203
+        if ($objMember->password != '')
204
+        {
205
+          $objWidget->mandatory = false;
206
+        }
207
+
208
+        $objWidget->rowClassConfirm = 'row_' . ++$row . ((($row % 2) == 0) ? ' even' : ' odd');
209
+      }
210
+
211
+      // Validate the form data
212
+      if (\Input::post('FORM_SUBMIT') == 'tl_member_' . $this->id)
213
+      {
214
+        $objWidget->validate();
215
+        $varValue = $objWidget->value;
216
+
217
+        $rgxp = $arrData['eval']['rgxp'];
218
+
219
+        // Convert date formats into timestamps (check the eval setting first -> #3063)
220
+        if ($varValue != '' && in_array($rgxp, array('date', 'time', 'datim')))
221
+        {
222
+          try
223
+          {
224
+            $objDate = new \Date($varValue, \Date::getFormatFromRgxp($rgxp));
225
+            $varValue = $objDate->tstamp;
226
+          }
227
+          catch (\OutOfBoundsException $e)
228
+          {
229
+            $objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidDate'], $varValue));
230
+          }
231
+        }
232
+
233
+        // Make sure that unique fields are unique (check the eval setting first -> #3063)
234
+        if ($arrData['eval']['unique'] && $varValue != '' && !$this->Database->isUniqueValue('tl_member', $field, $varValue, $this->User->id))
235
+        {
236
+          $objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['unique'], $arrData['label'][0] ?: $field));
237
+        }
238
+
239
+        // Trigger the save_callback (see #5247)
240
+        if ($objWidget->submitInput() && !$objWidget->hasErrors() && is_array($arrData['save_callback']))
241
+        {
242
+          foreach ($arrData['save_callback'] as $callback)
243
+          {
244
+            try
245
+            {
246
+              if (is_array($callback))
247
+              {
248
+                $this->import($callback[0]);
249
+                $varValue = $this->{$callback[0]}->{$callback[1]}($varValue, $this->User, $this);
250
+              }
251
+              elseif (is_callable($callback))
252
+              {
253
+                $varValue = $callback($varValue, $this->User, $this);
254
+              }
255
+            }
256
+            catch (\Exception $e)
257
+            {
258
+              $objWidget->class = 'error';
259
+              $objWidget->addError($e->getMessage());
260
+            }
261
+          }
262
+        }
263
+
264
+        // Do not submit the field if there are errors
265
+        if ($objWidget->hasErrors())
266
+        {
267
+          $doNotSubmit = true;
268
+        }
269
+        elseif ($objWidget->submitInput())
270
+        {
271
+          // Store the form data
272
+          $_SESSION['FORM_DATA'][$field] = $varValue;
273
+
274
+          // Set the correct empty value (see #6284, #6373)
275
+          if ($varValue === '')
276
+          {
277
+            $varValue = $objWidget->getEmptyValue();
278
+          }
279
+
280
+          // Encrypt the value (see #7815)
281
+          if ($arrData['eval']['encrypt'])
282
+          {
283
+            $varValue = \Encryption::encrypt($varValue);
284
+          }
285
+
286
+          // Set the new value
287
+          if ($varValue !== $this->User->$field)
288
+          {
289
+            $this->User->$field = $varValue;
290
+
291
+            // Set the new field in the member model
292
+            $blnModified = true;
293
+            $objMember->$field = $varValue;
294
+          }
295
+        }
296
+      }
297
+
298
+      if ($objWidget instanceof \uploadable)
299
+      {
300
+        $hasUpload = true;
301
+      }
302
+
303
+      $temp = $objWidget->parse();
304
+
305
+      $this->Template->fields .= $temp;
306
+      $arrFields[$strGroup][$field] .= $temp;
307
+      ++$row;
308
+    }
309
+
310
+    // Save the model
311
+    if ($blnModified)
312
+    {
313
+      $objMember->tstamp = time();
314
+      $objMember->save();
315
+
316
+      // Create a new version
317
+      if ($GLOBALS['TL_DCA'][$strTable]['config']['enableVersioning'])
318
+      {
319
+        $objVersions->create();
320
+      }
321
+    }
322
+
323
+    $this->Template->hasError = $doNotSubmit;
324
+
325
+    // Redirect or reload if there was no error
326
+    if (\Input::post('FORM_SUBMIT') == 'tl_member_' . $this->id && !$doNotSubmit)
327
+    {
328
+      // HOOK: updated personal data
329
+      if (isset($GLOBALS['TL_HOOKS']['updatePersonalData']) && is_array($GLOBALS['TL_HOOKS']['updatePersonalData']))
330
+      {
331
+        foreach ($GLOBALS['TL_HOOKS']['updatePersonalData'] as $callback)
332
+        {
333
+          $this->import($callback[0]);
334
+          $this->{$callback[0]}->{$callback[1]}($this->User, $_SESSION['FORM_DATA'], $this);
335
+        }
336
+      }
337
+
338
+      // Call the onsubmit_callback
339
+      if (is_array($GLOBALS['TL_DCA']['tl_member']['config']['onsubmit_callback']))
340
+      {
341
+        foreach ($GLOBALS['TL_DCA']['tl_member']['config']['onsubmit_callback'] as $callback)
342
+        {
343
+          if (is_array($callback))
344
+          {
345
+            $this->import($callback[0]);
346
+            $this->{$callback[0]}->{$callback[1]}($this->User, $this);
347
+          }
348
+          elseif (is_callable($callback))
349
+          {
350
+            $callback($this->User, $this);
351
+          }
352
+        }
353
+      }
354
+
355
+      // Check whether there is a jumpTo page
356
+      if (($objJumpTo = $this->objModel->getRelated('jumpTo')) !== null)
357
+      {
358
+        $this->jumpToOrReload($objJumpTo->row());
359
+      }
360
+
361
+      \Message::addConfirmation($GLOBALS['TL_LANG']['MSC']['savedData']);
362
+      $this->reload();
363
+    }
364
+
365
+    $this->Template->loginDetails = $GLOBALS['TL_LANG']['tl_member']['loginDetails'];
366
+    $this->Template->addressDetails = $GLOBALS['TL_LANG']['tl_member']['addressDetails'];
367
+    $this->Template->contactDetails = $GLOBALS['TL_LANG']['tl_member']['contactDetails'];
368
+    $this->Template->personalData = $GLOBALS['TL_LANG']['tl_member']['personalData'];
369
+
370
+    // Add the groups
371
+    foreach ($arrFields as $k=>$v)
372
+    {
373
+      $this->Template->$k = $v; // backwards compatibility
374
+
375
+      $key = $k . (($k == 'personal') ? 'Data' : 'Details');
376
+      $arrGroups[$GLOBALS['TL_LANG']['tl_member'][$key]] = $v;
377
+    }
378
+
379
+    $this->Template->categories = $arrGroups;
380
+    $this->Template->formId = 'tl_member_' . $this->id;
381
+    $this->Template->slabel = specialchars($GLOBALS['TL_LANG']['MSC']['saveData']);
382
+    $this->Template->action = \Environment::get('indexFreeRequest');
383
+    $this->Template->enctype = $hasUpload ? 'multipart/form-data' : 'application/x-www-form-urlencoded';
384
+    $this->Template->rowLast = 'row_' . $row . ((($row % 2) == 0) ? ' even' : ' odd');
385
+    $this->Template->message = \Message::generate(false, true);
386
+  }
350 387
 }
... ...
@@ -30,291 +30,305 @@ namespace eSM_formilicious;
30 30
 class ModuleRegistration extends \Contao\ModuleRegistration
31 31
 {
32 32
 
33
-	/**
34
-	 * Generate the module
35
-	 */
36
-	protected function compile()
37
-	{
38
-		global $objPage;
39
-
40
-		$GLOBALS['TL_LANGUAGE'] = $objPage->language;
41
-
42
-		\System::loadLanguageFile('tl_member');
43
-		$this->loadDataContainer('tl_member');
44
-
45
-		// Call onload_callback (e.g. to check permissions)
46
-		if (is_array($GLOBALS['TL_DCA']['tl_member']['config']['onload_callback']))
47
-		{
48
-			foreach ($GLOBALS['TL_DCA']['tl_member']['config']['onload_callback'] as $callback)
49
-			{
50
-				if (is_array($callback))
51
-				{
52
-					$this->import($callback[0]);
53
-					$this->$callback[0]->$callback[1]();
54
-				}
55
-				elseif (is_callable($callback))
56
-				{
57
-					$callback();
58
-				}
59
-			}
60
-		}
61
-
62
-		// Activate account
63
-		if (\Input::get('token') != '')
64
-		{
65
-			$this->activateAcount();
66
-			return;
67
-		}
68
-
69
-		if ($this->memberTpl != '')
70
-		{
71
-			$this->Template = new \FrontendTemplate($this->memberTpl);
72
-			$this->Template->setData($this->arrData);
73
-		}
74
-
75
-		$this->Template->fields = '';
76
-		$this->Template->tableless = $this->tableless;
77
-		$objCaptcha = null;
78
-		$doNotSubmit = false;
79
-
80
-		// Captcha
81
-		if (!$this->disableCaptcha)
82
-		{
83
-			$arrCaptcha = array
84
-			(
85
-				'id' => 'registration',
86
-				'label' => $GLOBALS['TL_LANG']['MSC']['securityQuestion'],
87
-				'type' => 'captcha',
88
-				'mandatory' => true,
89
-				'required' => true,
90
-				'tableless' => $this->tableless
91
-			);
92
-
93
-			$strClass = $GLOBALS['TL_FFL']['captcha'];
94
-
95
-			// Fallback to default if the class is not defined
96
-			if (!class_exists($strClass))
97
-			{
98
-				$strClass = 'FormCaptcha';
99
-			}
100
-
101
-			$objCaptcha = new $strClass($arrCaptcha);
102
-
103
-			if (\Input::post('FORM_SUBMIT') == 'tl_registration')
104
-			{
105
-				$objCaptcha->validate();
106
-
107
-				if ($objCaptcha->hasErrors())
108
-				{
109
-					$doNotSubmit = true;
110
-				}
111
-			}
112
-		}
113
-
114
-		$arrUser = array();
115
-		$arrFields = array();
116
-		$hasUpload = false;
117
-		$i = 0;
118
-
119
-		// Build form
120
-		foreach ($this->editable as $fielddata)
121
-		{
122
-			// Split formilicious editable data in single vars
123
-			list($field,$fieldWidth,$fieldClr,$fieldMandatory) = array_values($fielddata);
124
-
125
-			$arrData = $GLOBALS['TL_DCA']['tl_member']['fields'][$field];
126
-
127
-			// Map checkboxWizard to regular checkbox widget
128
-			if ($arrData['inputType'] == 'checkboxWizard')
129
-			{
130
-				$arrData['inputType'] = 'checkbox';
131
-			}
132
-
133
-			$strClass = $GLOBALS['TL_FFL'][$arrData['inputType']];
134
-
135
-			// Continue if the class is not defined
136
-			if (!class_exists($strClass))
137
-			{
138
-				continue;
139
-			}
140
-
141
-			$arrData['eval']['tableless'] = $this->tableless;
142
-			$arrData['eval']['required'] = $arrData['eval']['mandatory'];
143
-
144
-			$objWidget = new $strClass($strClass::getAttributesFromDca($arrData, $field, $arrData['default'], '', '', $this));
145
-
146
-			$objWidget->storeValues = true;
147
-			$objWidget->rowClass = 'row_' . $i . (($i == 0) ? ' row_first' : '') . ((($i % 2) == 0) ? ' even' : ' odd');
148
-
149
-			// Extend with formilicious data
150
-			$objWidget->eSM_fl_width = $fieldWidth;
151
-			$objWidget->eSM_fl_clear = $fieldClr;
152
-			if ($fieldMandatory)
153
-			{
154
-				$objWidget->required = $fieldMandatory;
155
-				$objWidget->mandatory = $fieldMandatory;
156
-			} else {
157
-				$objWidget->required = false;
158
-				$objWidget->mandatory = false;
159
-			}
160
-			if (in_array($arrData['eval']['rgxp'], array('date','time','datim')))
161
-			{
162
-				$strDateFormatFunc = 'getNumeric'.ucfirst($arrData['eval']['rgxp']).'Format';
163
-				$objWidget->placeholder = \Date::getInputFormat(\Date::$strDateFormatFunc());
164
-				$objWidget->maxlength = strlen($objWidget->placeholder);
165
-			}
166
-
167
-			// Increase the row count if its a password field
168
-			if ($objWidget instanceof \FormPassword)
169
-			{
170
-				$objWidget->rowClassConfirm = 'row_' . ++$i . ((($i % 2) == 0) ? ' even' : ' odd');
171
-			}
172
-
173
-			// Validate input
174
-			if (\Input::post('FORM_SUBMIT') == 'tl_registration')
175
-			{
176
-				$objWidget->validate();
177
-				$varValue = $objWidget->value;
178
-
179
-				// Check whether the password matches the username
180
-				if ($objWidget instanceof \FormPassword && $varValue == \Input::post('username'))
181
-				{
182
-					$objWidget->addError($GLOBALS['TL_LANG']['ERR']['passwordName']);
183
-				}
184
-
185
-				$rgxp = $arrData['eval']['rgxp'];
186
-
187
-				// Convert date formats into timestamps (check the eval setting first -> #3063)
188
-				if (($rgxp == 'date' || $rgxp == 'time' || $rgxp == 'datim') && $varValue != '')
189
-				{
190
-					try
191
-					{
192
-						$objDate = new \Date($varValue);
193
-						$varValue = $objDate->tstamp;
194
-					}
195
-					catch (\OutOfBoundsException $e)
196
-					{
197
-						$objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidDate'], $varValue));
198
-					}
199
-				}
200
-
201
-				// Make sure that unique fields are unique (check the eval setting first -> #3063)
202
-				if ($arrData['eval']['unique'] && $varValue != '' && !$this->Database->isUniqueValue('tl_member', $field, $varValue))
203
-				{
204
-					$objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['unique'], $arrData['label'][0] ?: $field));
205
-				}
206
-
207
-				// Save callback
208
-				if ($objWidget->submitInput() && !$objWidget->hasErrors() && is_array($arrData['save_callback']))
209
-				{
210
-					foreach ($arrData['save_callback'] as $callback)
211
-					{
212
-						try
213
-						{
214
-							if (is_array($callback))
215
-							{
216
-								$this->import($callback[0]);
217
-								$varValue = $this->$callback[0]->$callback[1]($varValue, null);
218
-							}
219
-							elseif (is_callable($callback))
220
-							{
221
-								$varValue = $callback($varValue, null);
222
-							}
223
-						}
224
-						catch (\Exception $e)
225
-						{
226
-							$objWidget->class = 'error';
227
-							$objWidget->addError($e->getMessage());
228
-						}
229
-					}
230
-				}
231
-
232
-				// Store the current value
233
-				if ($objWidget->hasErrors())
234
-				{
235
-					$doNotSubmit = true;
236
-				}
237
-				elseif ($objWidget->submitInput())
238
-				{
239
-					// Set the correct empty value (see #6284, #6373)
240
-					if ($varValue === '')
241
-					{
242
-						$varValue = $objWidget->getEmptyValue();
243
-					}
244
-
245
-					$arrUser[$field] = $varValue;
246
-				}
247
-			}
248
-
249
-			if ($objWidget instanceof \uploadable)
250
-			{
251
-				$hasUpload = true;
252
-			}
253
-
254
-			$temp = $objWidget->parse();
255
-
256
-			$this->Template->fields .= $temp;
257
-			$arrFields[$arrData['eval']['feGroup']][$field] .= $temp;
258
-
259
-			++$i;
260
-		}
261
-
262
-		// Captcha
263
-		if (!$this->disableCaptcha)
264
-		{
265
-			$objCaptcha->rowClass = 'row_'.$i . (($i == 0) ? ' row_first' : '') . ((($i % 2) == 0) ? ' even' : ' odd');
266
-			$strCaptcha = $objCaptcha->parse();
267
-
268
-			$this->Template->fields .= $strCaptcha;
269
-			$arrFields['captcha'] .= $strCaptcha;
270
-		}
271
-
272
-		$this->Template->rowLast = 'row_' . ++$i . ((($i % 2) == 0) ? ' even' : ' odd');
273
-		$this->Template->enctype = $hasUpload ? 'multipart/form-data' : 'application/x-www-form-urlencoded';
274
-		$this->Template->hasError = $doNotSubmit;
275
-
276
-		// Create new user if there are no errors
277
-		if (\Input::post('FORM_SUBMIT') == 'tl_registration' && !$doNotSubmit)
278
-		{
279
-			$this->createNewUser($arrUser);
280
-		}
281
-
282
-		$this->Template->loginDetails = $GLOBALS['TL_LANG']['tl_member']['loginDetails'];
283
-		$this->Template->addressDetails = $GLOBALS['TL_LANG']['tl_member']['addressDetails'];
284
-		$this->Template->contactDetails = $GLOBALS['TL_LANG']['tl_member']['contactDetails'];
285
-		$this->Template->personalData = $GLOBALS['TL_LANG']['tl_member']['personalData'];
286
-		$this->Template->captchaDetails = $GLOBALS['TL_LANG']['MSC']['securityQuestion'];
287
-
288
-		// Add groups
289
-		foreach ($arrFields as $k=>$v)
290
-		{
291
-			$this->Template->$k = $v;
292
-		}
293
-
294
-		$this->Template->captcha = $arrFields['captcha'];
295
-		$this->Template->formId = 'tl_registration';
296
-		$this->Template->slabel = specialchars($GLOBALS['TL_LANG']['MSC']['register']);
297
-		$this->Template->action = \Environment::get('indexFreeRequest');
298
-
299
-		// HOOK: add memberlist fields
300
-		if (in_array('memberlist', \ModuleLoader::getActive()))
301
-		{
302
-			$this->Template->profile = $arrFields['profile'];
303
-			$this->Template->profileDetails = $GLOBALS['TL_LANG']['tl_member']['profileDetails'];
304
-		}
305
-
306
-		// HOOK: add newsletter fields
307
-		if (in_array('newsletter', \ModuleLoader::getActive()))
308
-		{
309
-			$this->Template->newsletter = $arrFields['newsletter'];
310
-			$this->Template->newsletterDetails = $GLOBALS['TL_LANG']['tl_member']['newsletterDetails'];
311
-		}
312
-
313
-		// HOOK: add helpdesk fields
314
-		if (in_array('helpdesk', \ModuleLoader::getActive()))
315
-		{
316
-			$this->Template->helpdesk = $arrFields['helpdesk'];
317
-			$this->Template->helpdeskDetails = $GLOBALS['TL_LANG']['tl_member']['helpdeskDetails'];
318
-		}
319
-	}
33
+  /**
34
+   * Generate the module
35
+   */
36
+  protected function compile()
37
+  {
38
+    /** @var \PageModel $objPage */
39
+    global $objPage;
40
+
41
+    $GLOBALS['TL_LANGUAGE'] = $objPage->language;
42
+
43
+    \System::loadLanguageFile('tl_member');
44
+    $this->loadDataContainer('tl_member');
45
+
46
+    // Call onload_callback (e.g. to check permissions)
47
+    if (is_array($GLOBALS['TL_DCA']['tl_member']['config']['onload_callback']))
48
+    {
49
+      foreach ($GLOBALS['TL_DCA']['tl_member']['config']['onload_callback'] as $callback)
50
+      {
51
+        if (is_array($callback))
52
+        {
53
+          $this->import($callback[0]);
54
+          $this->{$callback[0]}->{$callback[1]}();
55
+        }
56
+        elseif (is_callable($callback))
57
+        {
58
+          $callback();
59
+        }
60
+      }
61
+    }
62
+
63
+    // Activate account
64
+    if (\Input::get('token') != '')
65
+    {
66
+      $this->activateAcount();
67
+
68
+      return;
69
+    }
70
+
71
+    if ($this->memberTpl != '')
72
+    {
73
+      /** @var \FrontendTemplate|object $objTemplate */
74
+      $objTemplate = new \FrontendTemplate($this->memberTpl);
75
+
76
+      $this->Template = $objTemplate;
77
+      $this->Template->setData($this->arrData);
78
+    }
79
+
80
+    $this->Template->fields = '';
81
+    $this->Template->tableless = $this->tableless;
82
+    $objCaptcha = null;
83
+    $doNotSubmit = false;
84
+
85
+    // Predefine the group order (other groups will be appended automatically)
86
+    $arrGroups = array
87
+    (
88
+      'personal' => array(),
89
+      'address'  => array(),
90
+      'contact'  => array(),
91
+      'login'    => array(),
92
+      'profile'  => array()
93
+    );
94
+
95
+    // Captcha
96
+    if (!$this->disableCaptcha)
97
+    {
98
+      $arrCaptcha = array
99
+      (
100
+        'id' => 'registration',
101
+        'label' => $GLOBALS['TL_LANG']['MSC']['securityQuestion'],
102
+        'type' => 'captcha',
103
+        'mandatory' => true,
104
+        'required' => true,
105
+        'tableless' => $this->tableless
106
+      );
107
+
108
+      /** @var \FormCaptcha $strClass */
109
+      $strClass = $GLOBALS['TL_FFL']['captcha'];
110
+
111
+      // Fallback to default if the class is not defined
112
+      if (!class_exists($strClass))
113
+      {
114
+        $strClass = 'FormCaptcha';
115
+      }
116
+
117
+      /** @var \FormCaptcha $objCaptcha */
118
+      $objCaptcha = new $strClass($arrCaptcha);
119
+
120
+      if (\Input::post('FORM_SUBMIT') == 'tl_registration')
121
+      {
122
+        $objCaptcha->validate();
123
+
124
+        if ($objCaptcha->hasErrors())
125
+        {
126
+          $doNotSubmit = true;
127
+        }
128
+      }
129
+    }
130
+
131
+    $arrUser = array();
132
+    $arrFields = array();
133
+    $hasUpload = false;
134
+    $i = 0;
135
+
136
+    // Build form
137
+    foreach ($this->editable as $fielddata)
138
+    {
139
+      // Split formilicious editable data in single vars
140
+      list($field,$fieldWidth,$fieldClr,$fieldMandatory) = array_values($fielddata);
141
+
142
+      $arrData = $GLOBALS['TL_DCA']['tl_member']['fields'][$field];
143
+
144
+      // Map checkboxWizards to regular checkbox widgets
145
+      if ($arrData['inputType'] == 'checkboxWizard')
146
+      {
147
+        $arrData['inputType'] = 'checkbox';
148
+      }
149
+
150
+      // Map fileTrees to upload widgets (see #8091)
151
+      if ($arrData['inputType'] == 'fileTree')
152
+      {
153
+        $arrData['inputType'] = 'upload';
154
+      }
155
+
156
+      /** @var \Widget $strClass */
157
+      $strClass = $GLOBALS['TL_FFL'][$arrData['inputType']];
158
+
159
+      // Continue if the class is not defined
160
+      if (!class_exists($strClass))
161
+      {
162
+        continue;
163
+      }
164
+
165
+      $arrData['eval']['tableless'] = $this->tableless;
166
+      $arrData['eval']['required'] = $arrData['eval']['mandatory'];
167
+
168
+      $objWidget = new $strClass($strClass::getAttributesFromDca($arrData, $field, $arrData['default'], '', '', $this));
169
+
170
+      $objWidget->storeValues = true;
171
+      $objWidget->rowClass = 'row_' . $i . (($i == 0) ? ' row_first' : '') . ((($i % 2) == 0) ? ' even' : ' odd');
172
+
173
+      // Extend with formilicious data
174
+      $objWidget->eSM_fl_width = $fieldWidth;
175
+      $objWidget->eSM_fl_clear = $fieldClr;
176
+      if ($fieldMandatory)
177
+      {
178
+        $objWidget->required = $fieldMandatory;
179
+        $objWidget->mandatory = $fieldMandatory;
180
+      } else {
181
+        $objWidget->required = false;
182
+        $objWidget->mandatory = false;
183
+      }
184
+      if (in_array($arrData['eval']['rgxp'], array('date','time','datim')))
185
+      {
186
+        $strDateFormatFunc = 'getNumeric'.ucfirst($arrData['eval']['rgxp']).'Format';
187
+        $objWidget->placeholder = \Date::getInputFormat(\Date::$strDateFormatFunc());
188
+        $objWidget->maxlength = strlen($objWidget->placeholder);
189
+      }
190
+
191
+      // Increase the row count if its a password field
192
+      if ($objWidget instanceof \FormPassword)
193
+      {
194
+        $objWidget->rowClassConfirm = 'row_' . ++$i . ((($i % 2) == 0) ? ' even' : ' odd');
195
+      }
196
+
197
+      // Validate input
198
+      if (\Input::post('FORM_SUBMIT') == 'tl_registration')
199
+      {
200
+        $objWidget->validate();
201
+        $varValue = $objWidget->value;
202
+
203
+        // Check whether the password matches the username
204
+        if ($objWidget instanceof \FormPassword && \Encryption::verify(\Input::post('username'), $varValue))
205
+        {
206
+          $objWidget->addError($GLOBALS['TL_LANG']['ERR']['passwordName']);
207
+        }
208
+
209
+        $rgxp = $arrData['eval']['rgxp'];
210
+
211
+        // Convert date formats into timestamps (check the eval setting first -> #3063)
212
+        if ($varValue != '' && in_array($rgxp, array('date', 'time', 'datim')))
213
+        {
214
+          try
215
+          {
216
+            $objDate = new \Date($varValue, \Date::getFormatFromRgxp($rgxp));
217
+            $varValue = $objDate->tstamp;
218
+          }
219
+          catch (\OutOfBoundsException $e)
220
+          {
221
+            $objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidDate'], $varValue));
222
+          }
223
+        }
224
+
225
+        // Make sure that unique fields are unique (check the eval setting first -> #3063)
226
+        if ($arrData['eval']['unique'] && $varValue != '' && !$this->Database->isUniqueValue('tl_member', $field, $varValue))
227
+        {
228
+          $objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['unique'], $arrData['label'][0] ?: $field));
229
+        }
230
+
231
+        // Save callback
232
+        if ($objWidget->submitInput() && !$objWidget->hasErrors() && is_array($arrData['save_callback']))
233
+        {
234
+          foreach ($arrData['save_callback'] as $callback)
235
+          {
236
+            try
237
+            {
238
+              if (is_array($callback))
239
+              {
240
+                $this->import($callback[0]);
241
+                $varValue = $this->{$callback[0]}->{$callback[1]}($varValue, null);
242
+              }
243
+              elseif (is_callable($callback))
244
+              {
245
+                $varValue = $callback($varValue, null);
246
+              }
247
+            }
248
+            catch (\Exception $e)
249
+            {
250
+              $objWidget->class = 'error';
251
+              $objWidget->addError($e->getMessage());
252
+            }
253
+          }
254
+        }
255
+
256
+        // Store the current value
257
+        if ($objWidget->hasErrors())
258
+        {
259
+          $doNotSubmit = true;
260
+        }
261
+        elseif ($objWidget->submitInput())
262
+        {
263
+          // Set the correct empty value (see #6284, #6373)
264
+          if ($varValue === '')
265
+          {
266
+            $varValue = $objWidget->getEmptyValue();
267
+          }
268
+
269
+          // Encrypt the value (see #7815)
270
+          if ($arrData['eval']['encrypt'])
271
+          {
272
+            $varValue = \Encryption::encrypt($varValue);
273
+          }
274
+
275
+          // Set the new value
276
+          $arrUser[$field] = $varValue;
277
+        }
278
+      }
279
+
280
+      if ($objWidget instanceof \uploadable)
281
+      {
282
+        $hasUpload = true;
283
+      }
284
+
285
+      $temp = $objWidget->parse();
286
+
287
+      $this->Template->fields .= $temp;
288
+      $arrFields[$arrData['eval']['feGroup']][$field] .= $temp;
289
+
290
+      ++$i;
291
+    }
292
+
293
+    // Captcha
294
+    if (!$this->disableCaptcha)
295
+    {
296
+      $objCaptcha->rowClass = 'row_'.$i . (($i == 0) ? ' row_first' : '') . ((($i % 2) == 0) ? ' even' : ' odd');
297
+      $strCaptcha = $objCaptcha->parse();
298
+
299
+      $this->Template->fields .= $strCaptcha;
300
+      $arrFields['captcha']['captcha'] .= $strCaptcha;
301
+    }
302
+
303
+    $this->Template->rowLast = 'row_' . ++$i . ((($i % 2) == 0) ? ' even' : ' odd');
304
+    $this->Template->enctype = $hasUpload ? 'multipart/form-data' : 'application/x-www-form-urlencoded';
305
+    $this->Template->hasError = $doNotSubmit;
306
+
307
+    // Create new user if there are no errors
308
+    if (\Input::post('FORM_SUBMIT') == 'tl_registration' && !$doNotSubmit)
309
+    {
310
+      $this->createNewUser($arrUser);
311
+    }
312
+
313
+    $this->Template->loginDetails = $GLOBALS['TL_LANG']['tl_member']['loginDetails'];
314
+    $this->Template->addressDetails = $GLOBALS['TL_LANG']['tl_member']['addressDetails'];
315
+    $this->Template->contactDetails = $GLOBALS['TL_LANG']['tl_member']['contactDetails'];
316
+    $this->Template->personalData = $GLOBALS['TL_LANG']['tl_member']['personalData'];
317
+    $this->Template->captchaDetails = $GLOBALS['TL_LANG']['MSC']['securityQuestion'];
318
+
319
+    // Add the groups
320
+    foreach ($arrFields as $k=>$v)
321
+    {
322
+      $this->Template->$k = $v; // backwards compatibility
323
+
324
+      $key = $k . (($k == 'personal') ? 'Data' : 'Details');
325
+      $arrGroups[$GLOBALS['TL_LANG']['tl_member'][$key]] = $v;
326
+    }
327
+
328
+    $this->Template->categories = $arrGroups;
329
+    $this->Template->formId = 'tl_registration';
330
+    $this->Template->slabel = specialchars($GLOBALS['TL_LANG']['MSC']['register']);
331
+    $this->Template->action = \Environment::get('indexFreeRequest');
332
+    $this->Template->captcha = $arrFields['captcha']['captcha']; // backwards compatibility
333
+  }
320 334
 }