1 <?php
2
3 define('REX_FORM_ERROR_VIOLATE_UNIQUE_KEY', 1062);
4
5 6 7 8 9 10 11 12 13 14 15
16 class rex_form extends rex_form_base
17 {
18 use rex_factory_trait;
19
20 protected $tableName;
21 protected $whereCondition;
22 protected $mode;
23 protected $db;
24 protected $sql;
25 protected $languageSupport;
26
27 28 29
30 protected function __construct($tableName, $fieldset, $whereCondition, $method = 'post', $debug = false, $db = 1)
31 {
32 $name = md5($tableName . $whereCondition . $method);
33
34 parent::__construct($fieldset, $name, $method, $debug);
35
36 $this->tableName = $tableName;
37 $this->whereCondition = $whereCondition;
38 $this->languageSupport = [];
39
40 $this->db = $db;
41 $this->sql = rex_sql::factory($db);
42 $this->sql->setDebug($this->debug);
43 $this->sql->setQuery('SELECT * FROM ' . $tableName . ' WHERE ' . $this->whereCondition . ' LIMIT 2');
44
45 $this->setFormId('rex-addon-editmode');
46
47
48 $numRows = $this->sql->getRows();
49 if ($numRows == 0) {
50
51 $this->setEditMode(false);
52 } elseif ($numRows == 1) {
53
54 $this->setEditMode(true);
55 } else {
56 throw new rex_exception('rex_form: Die gegebene Where-Bedingung führt nicht zu einem eindeutigen Datensatz!');
57 }
58
59
60 if (rex::isBackend()) {
61 $this->loadBackendConfig();
62 }
63 }
64
65 66 67 68 69 70 71 72 73 74 75 76
77 public static function factory($tableName, $fieldset, $whereCondition, $method = 'post', $debug = false, $db = 1)
78 {
79 $class = static::getFactoryClass();
80 return new $class($tableName, $fieldset, $whereCondition, $method, $debug, $db);
81 }
82
83 84 85
86 protected function loadBackendConfig()
87 {
88 parent::loadBackendConfig();
89
90 $func = rex_request('func', 'string');
91
92 $this->addParam('func', $func);
93 $this->addParam('list', rex_request('list', 'string'));
94
95 $controlFields = [];
96 $controlFields['save'] = rex_i18n::msg('form_save');
97 $controlFields['apply'] = $func == 'edit' ? rex_i18n::msg('form_apply') : '';
98 $controlFields['delete'] = $func == 'edit' ? rex_i18n::msg('form_delete') : '';
99 $controlFields['reset'] = '';
100 $controlFields['abort'] = rex_i18n::msg('form_abort');
101
102
103 $controlFields = rex_extension::registerPoint(new rex_extension_point('REX_FORM_CONTROL_FIELDS', $controlFields, ['form' => $this]));
104
105 $controlElements = [];
106 foreach ($controlFields as $name => $label) {
107 if ($label) {
108 $attr = ['type' => 'submit', 'internal::useArraySyntax' => false, 'internal::fieldSeparateEnding' => true];
109
110 if ($name === 'abort' || $name === 'delete') {
111 $attr['formnovalidate'] = 'formnovalidate';
112 }
113 $controlElements[$name] = $this->addField(
114 'button',
115 $name,
116 $label,
117 $attr,
118 false
119 );
120 } else {
121 $controlElements[$name] = null;
122 }
123 }
124
125 $this->addControlField(
126 $controlElements['save'],
127 $controlElements['apply'],
128 $controlElements['delete'],
129 $controlElements['reset'],
130 $controlElements['abort']
131 );
132 }
133
134 135 136 137 138 139 140 141 142
143 public function addPrioField($name, $value = null, array $attributes = [])
144 {
145 $attributes['internal::fieldClass'] = 'rex_form_prio_element';
146 if (!isset($attributes['class'])) {
147 $attributes['class'] = 'form-control';
148 }
149 $field = $this->addField('', $name, $value, $attributes, true);
150 return $field;
151 }
152
153 154 155
156 public function getWhereCondition()
157 {
158 return $this->whereCondition;
159 }
160
161 162 163 164 165 166
167 public function setLanguageSupport($idField, $clangField)
168 {
169 $this->languageSupport['id'] = $idField;
170 $this->languageSupport['clang'] = $clangField;
171 }
172
173 174 175
176 public function setEditMode($isEditMode)
177 {
178 if ($isEditMode) {
179 $this->mode = 'edit';
180 } else {
181 $this->mode = 'add';
182 }
183 }
184
185 186 187 188 189
190 public function isEditMode()
191 {
192 return $this->mode == 'edit';
193 }
194
195 196 197
198 public function getTableName()
199 {
200 return $this->tableName;
201 }
202
203 204 205
206 public function getSql()
207 {
208 return $this->sql;
209 }
210
211 protected function getId($name)
212 {
213 return $this->tableName . '_' . $this->fieldset . '_' . $name;
214 }
215
216 protected function getValue($name)
217 {
218 if ($this->sql->getRows() == 1 && $this->sql->hasValue($name)) {
219 return $this->sql->getValue($name);
220 }
221
222 return null;
223 }
224
225 226 227 228
229 protected function preSave($fieldsetName, $fieldName, $fieldValue, rex_sql $saveSql)
230 {
231 static $setOnce = false;
232
233 if (!$setOnce) {
234 $fieldnames = $this->sql->getFieldnames();
235
236 if (in_array('updateuser', $fieldnames)) {
237 $saveSql->setValue('updateuser', rex::getUser()->getValue('login'));
238 }
239
240 if (in_array('updatedate', $fieldnames)) {
241 $saveSql->setDateTimeValue('updatedate', time());
242 }
243
244 if (!$this->isEditMode()) {
245 if (in_array('createuser', $fieldnames)) {
246 $saveSql->setValue('createuser', rex::getUser()->getValue('login'));
247 }
248
249 if (in_array('createdate', $fieldnames)) {
250 $saveSql->setDateTimeValue('createdate', time());
251 }
252 }
253 $setOnce = true;
254 }
255
256 return $fieldValue;
257 }
258
259 260 261 262 263
264 public function equals($form)
265 {
266 return
267 $form instanceof self &&
268 $this->getTableName() == $form->getTableName() &&
269 $this->getWhereCondition() == $form->getWhereCondition();
270 }
271
272 273 274 275 276 277 278 279 280 281
282 protected function save()
283 {
284 $sql = rex_sql::factory($this->db);
285 $sql->setDebug($this->debug);
286 $sql->setTable($this->tableName);
287
288 $values = [];
289 foreach ($this->getSaveElements() as $fieldsetName => $fieldsetElements) {
290 foreach ($fieldsetElements as $element) {
291
292 if (strpos($element->getAttribute('class'), 'form-control-static') !== false) {
293 continue;
294 }
295
296 $fieldName = $element->getFieldName();
297 $fieldValue = $element->getSaveValue();
298
299
300 $fieldValue = $this->preSave($fieldsetName, $fieldName, $fieldValue, $sql);
301
302 if (is_string($fieldValue)) {
303 $fieldValue = trim($fieldValue);
304 }
305 $values[$fieldName] = $fieldValue;
306 }
307 }
308
309 try {
310 if ($this->isEditMode()) {
311 $sql->setValues($values);
312 $sql->setWhere($this->whereCondition);
313 $sql->update();
314 } else {
315 if (count($this->languageSupport)) {
316 foreach (rex_clang::getAllIds() as $clang_id) {
317 $sql->setTable($this->tableName);
318 $sql->addGlobalCreateFields();
319 $sql->addGlobalUpdateFields();
320 if (!isset($id)) {
321 $id = $sql->setNewId($this->languageSupport['id']);
322 } else {
323 $sql->setValue($this->languageSupport['id'], $id);
324 }
325 $sql->setValue($this->languageSupport['clang'], $clang_id);
326 $sql->setValues($values);
327 $sql->insert();
328 }
329 } else {
330 $sql->setValues($values);
331 $sql->insert();
332 }
333 }
334 $saved = true;
335 } catch (rex_sql_exception $e) {
336 $saved = false;
337 }
338
339
340 if ($saved) {
341 $saved = rex_extension::registerPoint(new rex_extension_point('REX_FORM_SAVED', $saved, ['form' => $this, 'sql' => $sql]));
342 } else {
343 $saved = $sql->getMysqlErrno();
344 }
345
346 return $saved;
347 }
348
349 350 351
352 protected function delete()
353 {
354 $deleteSql = rex_sql::factory($this->db);
355 $deleteSql->setDebug($this->debug);
356 $deleteSql->setTable($this->tableName);
357 $deleteSql->setWhere($this->whereCondition);
358
359 try {
360 $deleteSql->delete();
361 $deleted = true;
362 } catch (rex_sql_exception $e) {
363 $deleted = false;
364 }
365
366
367 if ($deleted) {
368 $deleted = rex_extension::registerPoint(new rex_extension_point('REX_FORM_DELETED', $deleted, ['form' => $this, 'sql' => $deleteSql]));
369 } else {
370 $deleted = $deleteSql->getMysqlErrno();
371 }
372
373 return $deleted;
374 }
375 }
376