1
|
|
|
<?php |
2
|
|
|
/*************************************************************************** |
3
|
|
|
* for license information see LICENSE.md |
4
|
|
|
***************************************************************************/ |
5
|
|
|
|
6
|
|
|
/** |
7
|
|
|
* Class rowEditor |
8
|
|
|
*/ |
9
|
|
|
class rowEditor |
10
|
|
|
{ |
11
|
|
|
public $sTable; |
12
|
|
|
public $sAutoIncrementField = null; |
13
|
|
|
public $pk; // (idx:name; type, default, nullable, value, insertfunction) |
14
|
|
|
public $fields; // (idx:name; type, default, nullable, value, changed, insertfunction) |
15
|
|
|
|
16
|
|
|
// status var |
17
|
|
|
public $bLoaded = false; |
18
|
|
|
public $bExist = false; |
19
|
|
|
public $bAddNew = false; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* primaryKey may be an array |
23
|
|
|
* |
24
|
|
|
* @param string $sTable |
25
|
|
|
*/ |
26
|
|
|
public function __construct($sTable) |
27
|
|
|
{ |
28
|
|
|
$this->pk = []; |
29
|
|
|
$this->fields = []; |
30
|
|
|
$this->sTable = $sTable; |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* @param string $sField |
35
|
|
|
* @param $nDefault |
36
|
|
|
* @param bool $bNullable |
37
|
|
|
* @param int $nInsertFunction |
38
|
|
|
*/ |
39
|
|
|
public function addPKInt($sField, $nDefault, $bNullable, $nInsertFunction = RE_INSERT_NOTHING): void |
40
|
|
|
{ |
41
|
|
|
$this->pk[$sField] = [ |
42
|
|
|
'type' => RE_TYPE_INT, |
43
|
|
|
'default' => $nDefault, |
44
|
|
|
'nullable' => $bNullable, |
45
|
|
|
'value' => $nDefault, |
46
|
|
|
'insertfunction' => $nInsertFunction, |
47
|
|
|
]; |
48
|
|
|
|
49
|
|
|
if (($nInsertFunction & RE_INSERT_AUTOINCREMENT) == RE_INSERT_AUTOINCREMENT) { |
50
|
|
|
$this->sAutoIncrementField = $sField; |
51
|
|
|
} |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* @param $sField |
56
|
|
|
* @param $nDefault |
57
|
|
|
* @param $bNullable |
58
|
|
|
* @param int $nInsertFunction |
59
|
|
|
*/ |
60
|
|
View Code Duplication |
public function addPKFloat($sField, $nDefault, $bNullable, $nInsertFunction = RE_INSERT_NOTHING): void |
|
|
|
|
61
|
|
|
{ |
62
|
|
|
$this->pk[$sField] = [ |
63
|
|
|
'type' => RE_TYPE_FLOAT, |
64
|
|
|
'default' => $nDefault, |
65
|
|
|
'nullable' => $bNullable, |
66
|
|
|
'value' => $nDefault, |
67
|
|
|
'insertfunction' => $nInsertFunction, |
68
|
|
|
]; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* @param $sField |
73
|
|
|
* @param $nDefault |
74
|
|
|
* @param $bNullable |
75
|
|
|
* @param int $nInsertFunction |
76
|
|
|
*/ |
77
|
|
View Code Duplication |
public function addPKDouble($sField, $nDefault, $bNullable, $nInsertFunction = RE_INSERT_NOTHING): void |
|
|
|
|
78
|
|
|
{ |
79
|
|
|
$this->pk[$sField] = [ |
80
|
|
|
'type' => RE_TYPE_DOUBLE, |
81
|
|
|
'default' => $nDefault, |
82
|
|
|
'nullable' => $bNullable, |
83
|
|
|
'value' => $nDefault, |
84
|
|
|
'insertfunction' => $nInsertFunction, |
85
|
|
|
]; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* @param $sField |
90
|
|
|
* @param $sDefault |
91
|
|
|
* @param $bNullable |
92
|
|
|
* @param int $nInsertFunction |
93
|
|
|
*/ |
94
|
|
|
public function addPKString($sField, $sDefault, $bNullable, $nInsertFunction = RE_INSERT_NOTHING): void |
95
|
|
|
{ |
96
|
|
|
if (($nInsertFunction & RE_INSERT_AUTOUUID) == RE_INSERT_AUTOUUID) { |
97
|
|
|
die('rowEditor: RE_INSERT_AUTOUUID not supported for primary key fields'); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
$this->pk[$sField] = [ |
101
|
|
|
'type' => RE_TYPE_STRING, |
102
|
|
|
'default' => $sDefault, |
103
|
|
|
'nullable' => $bNullable, |
104
|
|
|
'value' => $sDefault, |
105
|
|
|
'insertfunction' => $nInsertFunction, |
106
|
|
|
]; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* @param $sField |
111
|
|
|
* @param $bDefault |
112
|
|
|
* @param $bNullable |
113
|
|
|
* @param int $nInsertFunction |
114
|
|
|
*/ |
115
|
|
View Code Duplication |
public function addPKBoolean($sField, $bDefault, $bNullable, $nInsertFunction = RE_INSERT_NOTHING): void |
|
|
|
|
116
|
|
|
{ |
117
|
|
|
$this->pk[$sField] = [ |
118
|
|
|
'type' => RE_TYPE_BOOLEAN, |
119
|
|
|
'default' => $bDefault, |
120
|
|
|
'nullable' => $bNullable, |
121
|
|
|
'value' => $bDefault, |
122
|
|
|
'insertfunction' => $nInsertFunction, |
123
|
|
|
]; |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* @param $sField |
128
|
|
|
* @param $dDefault |
129
|
|
|
* @param $bNullable |
130
|
|
|
* @param int $nInsertFunction |
131
|
|
|
*/ |
132
|
|
View Code Duplication |
public function addPKDate($sField, $dDefault, $bNullable, $nInsertFunction = RE_INSERT_NOTHING): void |
|
|
|
|
133
|
|
|
{ |
134
|
|
|
$this->pk[$sField] = [ |
135
|
|
|
'type' => RE_TYPE_DATE, |
136
|
|
|
'default' => $dDefault, |
137
|
|
|
'nullable' => $bNullable, |
138
|
|
|
'value' => $dDefault, |
139
|
|
|
'insertfunction' => $nInsertFunction, |
140
|
|
|
]; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* @param string $sField |
145
|
|
|
* @param $nDefault |
146
|
|
|
* @param bool $bNullable |
147
|
|
|
* @param int $nInsertFunction |
148
|
|
|
*/ |
149
|
|
View Code Duplication |
public function addInt($sField, $nDefault, $bNullable, $nInsertFunction = RE_INSERT_NOTHING): void |
|
|
|
|
150
|
|
|
{ |
151
|
|
|
$this->fields[$sField] = [ |
152
|
|
|
'type' => RE_TYPE_INT, |
153
|
|
|
'default' => $nDefault, |
154
|
|
|
'nullable' => $bNullable, |
155
|
|
|
'value' => $nDefault, |
156
|
|
|
'changed => false', |
157
|
|
|
'insertfunction' => $nInsertFunction, |
158
|
|
|
]; |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* @param string $sField |
163
|
|
|
* @param int $nDefault |
164
|
|
|
* @param bool $bNullable |
165
|
|
|
* @param int $nInsertFunction |
166
|
|
|
*/ |
167
|
|
View Code Duplication |
public function addFloat($sField, $nDefault, $bNullable, $nInsertFunction = RE_INSERT_NOTHING): void |
|
|
|
|
168
|
|
|
{ |
169
|
|
|
$this->fields[$sField] = [ |
170
|
|
|
'type' => RE_TYPE_FLOAT, |
171
|
|
|
'default' => $nDefault, |
172
|
|
|
'nullable' => $bNullable, |
173
|
|
|
'value' => $nDefault, |
174
|
|
|
'changed => false', |
175
|
|
|
'insertfunction' => $nInsertFunction, |
176
|
|
|
]; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* @param string $sField |
181
|
|
|
* @param int $nDefault |
182
|
|
|
* @param bool $bNullable |
183
|
|
|
* @param int $nInsertFunction |
184
|
|
|
*/ |
185
|
|
View Code Duplication |
public function addDouble($sField, $nDefault, $bNullable, $nInsertFunction = RE_INSERT_NOTHING): void |
|
|
|
|
186
|
|
|
{ |
187
|
|
|
$this->fields[$sField] = [ |
188
|
|
|
'type' => RE_TYPE_DOUBLE, |
189
|
|
|
'default' => $nDefault, |
190
|
|
|
'nullable' => $bNullable, |
191
|
|
|
'value' => $nDefault, |
192
|
|
|
'changed => false', |
193
|
|
|
'insertfunction' => $nInsertFunction, |
194
|
|
|
]; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* @param string $sField |
199
|
|
|
* @param $sDefault |
200
|
|
|
* @param bool $bNullable |
201
|
|
|
* @param int $nInsertFunction |
202
|
|
|
*/ |
203
|
|
View Code Duplication |
public function addString($sField, $sDefault, $bNullable, $nInsertFunction = RE_INSERT_NOTHING): void |
|
|
|
|
204
|
|
|
{ |
205
|
|
|
$this->fields[$sField] = [ |
206
|
|
|
'type' => RE_TYPE_STRING, |
207
|
|
|
'default' => $sDefault, |
208
|
|
|
'nullable' => $bNullable, |
209
|
|
|
'value' => $sDefault, |
210
|
|
|
'changed => false', |
211
|
|
|
'insertfunction' => $nInsertFunction, |
212
|
|
|
]; |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* @param string $sField |
217
|
|
|
* @param $bDefault |
218
|
|
|
* @param bool $bNullable |
219
|
|
|
* @param int $nInsertFunction |
220
|
|
|
*/ |
221
|
|
View Code Duplication |
public function addBoolean($sField, $bDefault, $bNullable, $nInsertFunction = RE_INSERT_NOTHING): void |
|
|
|
|
222
|
|
|
{ |
223
|
|
|
$this->fields[$sField] = [ |
224
|
|
|
'type' => RE_TYPE_BOOLEAN, |
225
|
|
|
'default' => $bDefault, |
226
|
|
|
'nullable' => $bNullable, |
227
|
|
|
'value' => $bDefault, |
228
|
|
|
'changed => false', |
229
|
|
|
'insertfunction' => $nInsertFunction, |
230
|
|
|
]; |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** |
234
|
|
|
* @param string $sField |
235
|
|
|
* @param $dDefault |
236
|
|
|
* @param bool $bNullable |
237
|
|
|
* @param int $nInsertFunction |
238
|
|
|
*/ |
239
|
|
View Code Duplication |
public function addDate($sField, $dDefault, $bNullable, $nInsertFunction = RE_INSERT_NOTHING): void |
|
|
|
|
240
|
|
|
{ |
241
|
|
|
$this->fields[$sField] = [ |
242
|
|
|
'type' => RE_TYPE_DATE, |
243
|
|
|
'default' => $dDefault, |
244
|
|
|
'nullable' => $bNullable, |
245
|
|
|
'value' => $dDefault, |
246
|
|
|
'changed => false', |
247
|
|
|
'insertfunction' => $nInsertFunction, |
248
|
|
|
]; |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
/** |
252
|
|
|
* @param $sField |
253
|
|
|
*/ |
254
|
|
|
public function removePK($sField): void |
255
|
|
|
{ |
256
|
|
|
unset($this->pk[$sField]); |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* @param $sField |
261
|
|
|
*/ |
262
|
|
|
public function removeField($sField): void |
263
|
|
|
{ |
264
|
|
|
unset($this->fields[$sField]); |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
/* |
268
|
|
|
* PKValues may be an string, indized or ordered array |
269
|
|
|
* |
270
|
|
|
* @param $PKValues |
271
|
|
|
* |
272
|
|
|
* @return bool |
273
|
|
|
*/ |
274
|
|
|
public function load($PKValues) |
275
|
|
|
{ |
276
|
|
|
$this->pSetPK($PKValues); |
277
|
|
|
|
278
|
|
|
$this->bLoaded = true; |
279
|
|
|
$this->bAddNew = false; |
280
|
|
|
$this->bExist = false; |
281
|
|
|
|
282
|
|
|
$rs = sql($this->pBuildSelect()); |
|
|
|
|
283
|
|
|
if (!$r = sql_fetch_assoc($rs)) { |
|
|
|
|
284
|
|
|
$this->bExist = false; |
285
|
|
|
|
286
|
|
|
return false; |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
// assign values |
290
|
|
|
foreach ($this->fields as $k => $field) { |
291
|
|
|
$this->fields[$k]['value'] = $this->pFormatValue($this->fields[$k]['type'], $r[$k]); |
292
|
|
|
$this->fields[$k]['changed'] = false; |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
$this->bExist = true; |
296
|
|
|
|
297
|
|
|
return true; |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
/** |
301
|
|
|
* @param $PKValues |
302
|
|
|
*/ |
303
|
|
|
public function addNew($PKValues): void |
304
|
|
|
{ |
305
|
|
|
$this->pSetPK($PKValues); |
306
|
|
|
|
307
|
|
|
$this->bLoaded = true; |
308
|
|
|
$this->bExist = false; |
309
|
|
|
$this->bAddNew = true; |
310
|
|
|
} |
311
|
|
|
|
312
|
|
|
/** |
313
|
|
|
* @return bool |
314
|
|
|
*/ |
315
|
|
|
public function exist() |
316
|
|
|
{ |
317
|
|
|
return $this->bExist; |
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
/** |
321
|
|
|
* @param mixed $PKValues |
322
|
|
|
*/ |
323
|
|
|
public function pSetPK($PKValues): void |
324
|
|
|
{ |
325
|
|
|
$this->pResetValues(); |
326
|
|
|
|
327
|
|
|
foreach ($this->pk as $k => $field) { |
328
|
|
|
$this->pk[$k]['value'] = $field['default']; |
329
|
|
|
} |
330
|
|
|
|
331
|
|
|
if (is_array($PKValues)) { |
332
|
|
|
foreach ($PKValues as $k => $v) { |
333
|
|
|
$pkKey = $this->pGetPKKey($k); |
334
|
|
|
$this->pk[$pkKey]['value'] = $this->pFormatValue($this->pk[$pkKey]['type'], $v); |
335
|
|
|
} |
336
|
|
|
} else { |
337
|
|
|
$pkKey = $this->pGetPKKey(0); |
338
|
|
|
$this->pk[$pkKey]['value'] = $this->pFormatValue($this->pk[$pkKey]['type'], $PKValues); |
339
|
|
|
} |
340
|
|
|
} |
341
|
|
|
|
342
|
|
|
/** |
343
|
|
|
* @param $index |
344
|
|
|
* |
345
|
|
|
* @return int|string |
346
|
|
|
*/ |
347
|
|
|
public function pGetPKKey($index) |
348
|
|
|
{ |
349
|
|
|
if (isset($this->pk[$index])) { |
350
|
|
|
return $index; |
351
|
|
|
} |
352
|
|
|
|
353
|
|
|
$i = 0; |
354
|
|
|
foreach ($this->pk as $k => $v) { |
355
|
|
|
if ($i == $index) { |
356
|
|
|
return $k; |
357
|
|
|
} |
358
|
|
|
$i++; |
359
|
|
|
} |
360
|
|
|
} |
361
|
|
|
|
362
|
|
|
public function pResetValues(): void |
363
|
|
|
{ |
364
|
|
|
foreach ($this->fields as $k => $field) { |
365
|
|
|
$this->fields[$k]['value'] = $field['default']; |
366
|
|
|
$this->fields[$k]['changed'] = false; |
367
|
|
|
} |
368
|
|
|
} |
369
|
|
|
|
370
|
|
|
/** |
371
|
|
|
* @param $type |
372
|
|
|
* @param $value |
373
|
|
|
* |
374
|
|
|
* @return bool|false|int|null |
375
|
|
|
*/ |
376
|
|
|
public function pFormatValue($type, $value) |
377
|
|
|
{ |
378
|
|
|
if ($value === null) { |
379
|
|
|
return null; |
380
|
|
|
} |
381
|
|
|
|
382
|
|
|
if ($type == RE_TYPE_INT) { |
383
|
|
|
$value = (int) $value + 0; |
384
|
|
|
} elseif ($type == RE_TYPE_FLOAT) { |
385
|
|
|
$value = $value + 0; |
386
|
|
|
} elseif ($type == RE_TYPE_DOUBLE) { |
387
|
|
|
$value = $value + 0; |
388
|
|
|
} elseif ($type == RE_TYPE_BOOLEAN) { |
389
|
|
|
$value = (($value + 0) != 0); |
390
|
|
|
} elseif ($type == RE_TYPE_DATE) { |
391
|
|
|
if (!is_numeric($value)) { |
392
|
|
|
$value = strtotime($value); |
393
|
|
|
} |
394
|
|
|
} |
395
|
|
|
|
396
|
|
|
return $value; |
397
|
|
|
} |
398
|
|
|
|
399
|
|
|
/** |
400
|
|
|
* @param $type |
401
|
|
|
* @param $value |
402
|
|
|
* |
403
|
|
|
* @return false|int|string |
404
|
|
|
*/ |
405
|
|
|
public function pFormatValueSql($type, $value) |
406
|
|
|
{ |
407
|
|
|
if ($type == RE_TYPE_INT) { |
408
|
|
|
$value = (int) $value + 0; |
409
|
|
|
} elseif ($type == RE_TYPE_FLOAT) { |
410
|
|
|
$value = $value + 0; |
411
|
|
|
} elseif ($type == RE_TYPE_DOUBLE) { |
412
|
|
|
$value = $value + 0; |
413
|
|
|
} elseif ($type == RE_TYPE_BOOLEAN) { |
414
|
|
|
$value = (($value + 0) != 0) ? 1 : 0; |
415
|
|
|
} elseif ($type == RE_TYPE_DATE) { |
416
|
|
|
if (!is_numeric($value)) { |
417
|
|
|
$value = strtotime($value); |
418
|
|
|
} |
419
|
|
|
|
420
|
|
|
$value = strftime(DB_DATE_FORMAT, $value); |
421
|
|
|
} |
422
|
|
|
|
423
|
|
|
return $value; |
424
|
|
|
} |
425
|
|
|
|
426
|
|
|
/** |
427
|
|
|
* @return string |
428
|
|
|
*/ |
429
|
|
|
public function pBuildSelect() |
430
|
|
|
{ |
431
|
|
|
$fSelect = []; |
432
|
|
|
$sql = 'SELECT '; |
433
|
|
|
foreach ($this->fields as $k => $field) { |
434
|
|
|
$fSelect[] = '`' . sql_escape($k) . '`'; |
|
|
|
|
435
|
|
|
} |
436
|
|
|
$sql .= join(', ', $fSelect); |
437
|
|
|
|
438
|
|
|
$sql .= ' FROM `' . sql_escape($this->sTable) . '`'; |
|
|
|
|
439
|
|
|
$sql .= ' WHERE ' . $this->pBuildPK(); |
440
|
|
|
|
441
|
|
|
return $sql; |
442
|
|
|
} |
443
|
|
|
|
444
|
|
|
/** |
445
|
|
|
* @return string |
446
|
|
|
*/ |
447
|
|
|
public function pBuildPK() |
448
|
|
|
{ |
449
|
|
|
$fWhere = []; |
450
|
|
|
foreach ($this->pk as $k => $field) { |
451
|
|
|
if ($field['value'] === null) { |
452
|
|
|
$fWhere[] = 'ISNULL(`' . sql_escape($k) . '`)'; |
|
|
|
|
453
|
|
View Code Duplication |
} else { |
454
|
|
|
$fWhere[] = '`' . sql_escape($k) . '`=\'' . sql_escape($field['value']) . '\''; |
|
|
|
|
455
|
|
|
} |
456
|
|
|
} |
457
|
|
|
|
458
|
|
|
return join(' AND ', $fWhere); |
459
|
|
|
} |
460
|
|
|
|
461
|
|
|
/** |
462
|
|
|
* @param string $sField |
463
|
|
|
* |
464
|
|
|
* @return mixed |
465
|
|
|
*/ |
466
|
|
|
public function getValue($sField) |
467
|
|
|
{ |
468
|
|
|
if (isset($this->pk[$sField])) { |
469
|
|
|
return $this->pk[$sField]['value']; |
470
|
|
|
} |
471
|
|
|
|
472
|
|
|
return $this->fields[$sField]['value']; |
473
|
|
|
} |
474
|
|
|
|
475
|
|
|
/** |
476
|
|
|
* @param $sField |
477
|
|
|
* |
478
|
|
|
* @return mixed |
479
|
|
|
*/ |
480
|
|
|
public function getDefault($sField) |
481
|
|
|
{ |
482
|
|
|
return $this->fields[$sField]['default']; |
483
|
|
|
} |
484
|
|
|
|
485
|
|
|
/** |
486
|
|
|
* @param string $sField |
487
|
|
|
* |
488
|
|
|
* @return mixed |
489
|
|
|
*/ |
490
|
|
|
public function getChanged($sField) |
491
|
|
|
{ |
492
|
|
|
return $this->fields[$sField]['changed']; |
493
|
|
|
} |
494
|
|
|
|
495
|
|
|
/** |
496
|
|
|
* @return bool|null |
497
|
|
|
*/ |
498
|
|
|
public function getAnyChanged() |
499
|
|
|
{ |
500
|
|
|
foreach ($this->fields as $field) { |
501
|
|
|
if ($field['changed'] == true) { |
502
|
|
|
return true; |
503
|
|
|
} |
504
|
|
|
} |
505
|
|
|
} |
506
|
|
|
|
507
|
|
|
/** |
508
|
|
|
* @param string $sField |
509
|
|
|
* @param $sValue |
510
|
|
|
* @return bool |
511
|
|
|
*/ |
512
|
|
|
public function setValue($sField, $sValue) |
513
|
|
|
{ |
514
|
|
View Code Duplication |
if ($this->bLoaded == false || ($this->bAddNew == false && $this->bExist == false)) { |
|
|
|
|
515
|
|
|
return false; |
516
|
|
|
} |
517
|
|
|
|
518
|
|
|
$sFormatedValue = $this->pFormatValue($this->fields[$sField]['type'], $sValue); |
519
|
|
|
if ($this->fields[$sField]['type'] == RE_TYPE_FLOAT) { |
520
|
|
|
// Direct float comparison is deprecated and can result in last-digit errors. |
521
|
|
|
// Floats in OC database are only used for reasonably large numbers like coordinates, |
522
|
|
|
// waylengths and time estimates, so using a fixed epsilon threshold is safe: |
523
|
|
|
$changed = (abs($sFormatedValue - $this->fields[$sField]['value']) >= 1e-12); |
524
|
|
|
} else { |
525
|
|
|
$changed = ($sFormatedValue != $this->fields[$sField]['value']) || ($this->fields[$sField]['nullable'] && (($sFormatedValue === null) != ($this->fields[$sField]['value'] === null))); |
526
|
|
|
} |
527
|
|
|
if ($changed) { |
528
|
|
|
$this->fields[$sField]['value'] = $sFormatedValue; |
529
|
|
|
$this->fields[$sField]['changed'] = true; |
530
|
|
|
} |
531
|
|
|
|
532
|
|
|
return true; |
533
|
|
|
} |
534
|
|
|
|
535
|
|
|
/** |
536
|
|
|
* @return bool |
537
|
|
|
*/ |
538
|
|
|
public function save() |
539
|
|
|
{ |
540
|
|
View Code Duplication |
if ($this->bLoaded == false || ($this->bAddNew == false && $this->bExist == false)) { |
|
|
|
|
541
|
|
|
return false; |
542
|
|
|
} |
543
|
|
|
|
544
|
|
|
if ($this->bAddNew == true) { |
|
|
|
|
545
|
|
|
// INSERT |
546
|
|
|
$sql = $this->pBuildInsert(); |
547
|
|
|
|
548
|
|
|
if ($sql != '') { |
549
|
|
|
sql($sql); |
|
|
|
|
550
|
|
|
if (sql_affected_rows() == 0) { |
|
|
|
|
551
|
|
|
return false; |
552
|
|
|
} |
553
|
|
|
} else { |
554
|
|
|
return true; |
555
|
|
|
} |
556
|
|
|
|
557
|
|
|
if ($this->sAutoIncrementField != null) { |
558
|
|
|
$nInsertId = sql_insert_id(); |
|
|
|
|
559
|
|
|
|
560
|
|
|
$this->pk[$this->sAutoIncrementField]['value'] = $nInsertId; |
561
|
|
|
|
562
|
|
|
if (isset($this->fields[$this->sAutoIncrementField])) { |
563
|
|
|
$this->fields[$this->sAutoIncrementField]['value'] = $nInsertId; |
564
|
|
|
} |
565
|
|
|
} |
566
|
|
|
|
567
|
|
|
/* reload the record to get the actual stored values |
568
|
|
|
* (inserted values maybe truncated by mysql or trigger could modify values) |
569
|
|
|
*/ |
570
|
|
|
$pkv = []; |
571
|
|
|
foreach ($this->pk as $k => $v) { |
572
|
|
|
$pkv[$k] = $this->pk[$k]['value']; |
573
|
|
|
} |
574
|
|
|
$this->load($pkv); |
575
|
|
|
|
576
|
|
|
return true; |
577
|
|
|
} |
578
|
|
|
// UPDATE |
579
|
|
|
$sql = $this->pBuildUpdate(); |
580
|
|
|
|
581
|
|
|
if ($sql != '') { |
582
|
|
|
$rs = sql($sql); |
|
|
|
|
583
|
|
|
// @bug wrong method signature |
584
|
|
|
if (sql_affected_rows($rs) == 0) { |
|
|
|
|
585
|
|
|
return false; |
586
|
|
|
} |
587
|
|
|
} else { |
588
|
|
|
return true; |
589
|
|
|
} |
590
|
|
|
|
591
|
|
|
foreach ($this->fields as $k => $field) { |
592
|
|
|
$this->fields[$k]['changed'] = false; |
593
|
|
|
} |
594
|
|
|
|
595
|
|
|
return true; |
596
|
|
|
} |
597
|
|
|
|
598
|
|
|
public function reload(): void |
599
|
|
|
{ |
600
|
|
|
$pkv = []; |
601
|
|
|
foreach ($this->pk as $k => $v) { |
602
|
|
|
$pkv[$k] = $this->pk[$k]['value']; |
603
|
|
|
} |
604
|
|
|
$this->load($pkv); |
605
|
|
|
} |
606
|
|
|
|
607
|
|
|
/** |
608
|
|
|
* @return string |
609
|
|
|
*/ |
610
|
|
|
public function pBuildInsert() |
611
|
|
|
{ |
612
|
|
|
$sql = 'INSERT IGNORE INTO `' . sql_escape($this->sTable) . '` ('; |
|
|
|
|
613
|
|
|
|
614
|
|
|
$sFields = []; |
615
|
|
|
$sValues = []; |
616
|
|
|
|
617
|
|
|
foreach ($this->pk as $k => $field) { |
618
|
|
|
if (isset($this->fields[$k])) { |
619
|
|
|
continue; |
620
|
|
|
} |
621
|
|
|
|
622
|
|
|
if ($this->sAutoIncrementField == $k) { |
623
|
|
|
continue; |
624
|
|
|
} |
625
|
|
|
|
626
|
|
|
if (($field['insertfunction'] & RE_INSERT_IGNORE) == RE_INSERT_IGNORE) { |
627
|
|
|
continue; |
628
|
|
|
} |
629
|
|
|
|
630
|
|
|
$sFields[] = '`' . sql_escape($k) . '`'; |
|
|
|
|
631
|
|
|
|
632
|
|
View Code Duplication |
if ((($field['insertfunction'] & RE_INSERT_OVERWRITE) == RE_INSERT_OVERWRITE) || (($field['changed'] == false) && ($field['insertfunction'] != RE_INSERT_NOTHING))) { |
633
|
|
|
if (($field['insertfunction'] & RE_INSERT_NOW) == RE_INSERT_NOW) { |
634
|
|
|
$sValues[] = 'NOW()'; |
635
|
|
|
} else { |
636
|
|
|
$sValues[] = 'NULL'; |
637
|
|
|
} |
638
|
|
|
} else { |
639
|
|
|
if ($field['value'] === null) { |
640
|
|
|
$sValues[] = 'NULL'; |
641
|
|
|
} else { |
642
|
|
|
$sValues[] = '\'' . sql_escape($this->pFormatValueSql($field['type'], $field['value'])) . '\''; |
|
|
|
|
643
|
|
|
} |
644
|
|
|
} |
645
|
|
|
} |
646
|
|
|
|
647
|
|
|
foreach ($this->fields as $k => $field) { |
648
|
|
|
if (($field['insertfunction'] & RE_INSERT_IGNORE) == RE_INSERT_IGNORE) { |
649
|
|
|
continue; |
650
|
|
|
} |
651
|
|
|
|
652
|
|
|
$sFields[] = '`' . sql_escape($k) . '`'; |
|
|
|
|
653
|
|
|
|
654
|
|
View Code Duplication |
if ((($field['insertfunction'] & RE_INSERT_OVERWRITE) == RE_INSERT_OVERWRITE) || (($field['changed'] == false) && ($field['insertfunction'] != RE_INSERT_NOTHING))) { |
655
|
|
|
if (($field['insertfunction'] & RE_INSERT_NOW) == RE_INSERT_NOW) { |
656
|
|
|
$sValues[] = 'NOW()'; |
657
|
|
|
} else { |
658
|
|
|
$sValues[] = 'NULL'; |
659
|
|
|
} |
660
|
|
|
} else { |
661
|
|
|
if ($field['value'] === null) { |
662
|
|
|
$sValues[] = 'NULL'; |
663
|
|
|
} else { |
664
|
|
|
$sValues[] = '\'' . sql_escape($this->pFormatValueSql($field['type'], $field['value'])) . '\''; |
|
|
|
|
665
|
|
|
} |
666
|
|
|
} |
667
|
|
|
} |
668
|
|
|
$sql .= join(', ', $sFields); |
669
|
|
|
$sql .= ') VALUES ('; |
670
|
|
|
$sql .= join(', ', $sValues); |
671
|
|
|
$sql .= ')'; |
672
|
|
|
|
673
|
|
|
return $sql; |
674
|
|
|
} |
675
|
|
|
|
676
|
|
|
/** |
677
|
|
|
* @return string |
678
|
|
|
*/ |
679
|
|
|
public function pBuildUpdate() |
680
|
|
|
{ |
681
|
|
|
$sql = 'UPDATE IGNORE `' . sql_escape($this->sTable) . '` SET '; |
|
|
|
|
682
|
|
|
|
683
|
|
|
$sSet = ''; |
684
|
|
|
foreach ($this->fields as $k => $field) { |
685
|
|
|
if ($field['changed'] == true) { |
686
|
|
|
if ($sSet != '') { |
687
|
|
|
$sSet .= ', '; |
688
|
|
|
} |
689
|
|
|
|
690
|
|
|
if ($field['value'] === null) { |
691
|
|
|
$sSet .= '`' . sql_escape($k) . '`=NULL'; |
|
|
|
|
692
|
|
View Code Duplication |
} else { |
693
|
|
|
$sSet .= '`' . sql_escape($k) . '`=\'' . sql_escape($this->pFormatValueSql($field['type'], $field['value'])) . '\''; |
|
|
|
|
694
|
|
|
} |
695
|
|
|
} |
696
|
|
|
} |
697
|
|
|
|
698
|
|
|
if ($sSet == '') { |
699
|
|
|
return ''; |
700
|
|
|
} |
701
|
|
|
|
702
|
|
|
$sql .= $sSet; |
703
|
|
|
$sql .= ' WHERE '; |
704
|
|
|
$sql .= $this->pBuildPK(); |
705
|
|
|
|
706
|
|
|
return $sql; |
707
|
|
|
} |
708
|
|
|
|
709
|
|
|
/** |
710
|
|
|
* @param string $field |
711
|
|
|
* |
712
|
|
|
* @return bool |
713
|
|
|
*/ |
714
|
|
|
public function saveField($field) |
715
|
|
|
{ |
716
|
|
View Code Duplication |
if ($this->bLoaded == false || $this->bExist == false || $this->bAddNew == true) { |
|
|
|
|
717
|
|
|
return false; |
718
|
|
|
} |
719
|
|
|
|
720
|
|
|
if ($this->fields[$field]['changed'] == false) { |
721
|
|
|
return true; |
722
|
|
|
} |
723
|
|
|
|
724
|
|
|
if ($this->fields[$field]['value'] === null) { |
725
|
|
|
$sSet = '`' . sql_escape($field) . '`=NULL'; |
|
|
|
|
726
|
|
|
} else { |
727
|
|
|
$sSet = '`' . sql_escape($field) . '`=\'' . sql_escape($this->pFormatValueSql($this->fields[$field]['type'], $this->fields[$field]['value'])) . '\''; |
|
|
|
|
728
|
|
|
} |
729
|
|
|
|
730
|
|
|
$sql = 'UPDATE `' . sql_escape($this->sTable) . '` SET ' . $sSet; |
|
|
|
|
731
|
|
|
$sql .= ' WHERE '; |
732
|
|
|
$sql .= $this->pBuildPK(); |
733
|
|
|
|
734
|
|
|
sql($sql); |
|
|
|
|
735
|
|
|
if (sql_affected_rows() == 0) { |
|
|
|
|
736
|
|
|
return false; |
737
|
|
|
} |
738
|
|
|
|
739
|
|
|
$this->fields[$field]['changed'] = false; |
740
|
|
|
|
741
|
|
|
return true; |
742
|
|
|
} |
743
|
|
|
} |
744
|
|
|
|
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.