1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* |
4
|
|
|
* @package supernova |
5
|
|
|
* @version $Id$ |
6
|
|
|
* @copyright (c) 2009-2010 Gorlum for http://supernova.ws |
7
|
|
|
* @license http://opensource.org/licenses/gpl-license.php GNU Public License |
8
|
|
|
* |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* @ignore |
13
|
|
|
* Defining some constants |
14
|
|
|
*/ |
15
|
|
|
define('CACHER_NOT_INIT', -1); |
16
|
|
|
define('CACHER_NO_CACHE', 0); |
17
|
|
|
define('CACHER_XCACHE', 1); |
18
|
|
|
|
19
|
|
|
define('CACHER_LOCK_WAIT', 5); // maximum cacher wait for table unlock in seconds. Can be float |
20
|
|
|
|
21
|
|
|
// max timeout cacher can sleep in waiting for unlockDefault = 10000 ms = 0.01s |
22
|
|
|
// really it will sleep mt_rand(100, classCache::CACHER_LOCK_SLEEP) |
23
|
|
|
define('CACHER_LOCK_SLEEP', 10000); |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* |
27
|
|
|
* Basic cacher class that handles different cache engines |
28
|
|
|
* It's pretty smart to handle one cache instance for all application instances (if there is PHP-cacher installed) |
29
|
|
|
* Currently supported only XCache and no-cache (array) |
30
|
|
|
* With no-cache some advanced features would be unaccessible |
31
|
|
|
* Cacher works not only with single values. It's also support multidimensional arrays |
32
|
|
|
* Currently support is a bit limited - for example there is no "walk" function. However basic array abilities supported |
33
|
|
|
* You should NEVER operate with arrays inside of cacher and should ALWAYS use wrap-up functions |
34
|
|
|
* |
35
|
|
|
* |
36
|
|
|
* @property bool _INITIALIZED |
37
|
|
|
* @property array lng_stat_usage - Array for locale strings usage statistics |
38
|
|
|
* @property array tables |
39
|
|
|
* |
40
|
|
|
* @package supernova |
41
|
|
|
*/ |
42
|
|
|
class classCache { |
43
|
|
|
// CACHER_NOT_INIT - not initialized |
44
|
|
|
// CACHER_NO_CACHE - no cache - array() used |
45
|
|
|
// CACHER_XCACHE - xCache |
46
|
|
|
protected static $mode = CACHER_NOT_INIT; |
47
|
|
|
protected static $data; |
48
|
|
|
protected $prefix; |
49
|
|
|
|
50
|
|
|
protected static $cacheObject; |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* @return int |
54
|
|
|
*/ |
55
|
|
|
public function getMode() { |
56
|
|
|
return static::$mode; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
public function __construct($prefIn = 'CACHE_', $init_mode = false) { |
60
|
|
|
if (!($init_mode === false || $init_mode === CACHER_NO_CACHE || ($init_mode === CACHER_XCACHE && extension_loaded('xcache')))) { |
61
|
|
|
throw new UnexpectedValueException('Wrong work mode or current mode does not supported on your server'); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
$this->prefix = $prefIn; |
65
|
|
|
if (extension_loaded('xcache') && ($init_mode === CACHER_XCACHE || $init_mode === false)) { |
66
|
|
|
if (self::$mode === CACHER_NOT_INIT) { |
67
|
|
|
self::$mode = CACHER_XCACHE; |
68
|
|
|
} |
69
|
|
|
} else { |
70
|
|
|
if (self::$mode === CACHER_NOT_INIT) { |
71
|
|
|
self::$mode = CACHER_NO_CACHE; |
72
|
|
|
if (!self::$data) { |
73
|
|
|
self::$data = array(); |
74
|
|
|
} |
75
|
|
|
} |
76
|
|
|
} |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
public static function getInstance($prefIn = 'CACHE_', $table_name = '') { |
80
|
|
|
if (!isset(self::$cacheObject)) { |
81
|
|
|
$className = get_class(); |
82
|
|
|
self::$cacheObject = new $className($prefIn); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
return self::$cacheObject; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
public final function __clone() { |
89
|
|
|
// You NEVER need to copy cacher object or siblings |
90
|
|
|
throw new BadMethodCallException('Clone is not allowed'); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
// ------------------------------------------------------------------------- |
94
|
|
|
// Here comes low-level functions - those that directly works with cacher engines |
95
|
|
|
// ------------------------------------------------------------------------- |
96
|
|
View Code Duplication |
public function __set($name, $value) { |
|
|
|
|
97
|
|
|
switch (self::$mode) { |
98
|
|
|
case CACHER_NO_CACHE: |
99
|
|
|
self::$data[$this->prefix . $name] = $value; |
100
|
|
|
break; |
101
|
|
|
|
102
|
|
|
case CACHER_XCACHE: |
103
|
|
|
xcache_set($this->prefix . $name, $value); |
104
|
|
|
break; |
105
|
|
|
} |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
public function __get($name) { |
109
|
|
|
switch (self::$mode) { |
110
|
|
|
case CACHER_NO_CACHE: |
111
|
|
|
return self::$data[$this->prefix . $name]; |
112
|
|
|
break; |
|
|
|
|
113
|
|
|
|
114
|
|
|
case CACHER_XCACHE: |
115
|
|
|
return xcache_get($this->prefix . $name); |
116
|
|
|
break; |
|
|
|
|
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
return null; |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
public function __isset($name) { |
123
|
|
|
switch (self::$mode) { |
124
|
|
|
case CACHER_NO_CACHE: |
125
|
|
|
return isset(self::$data[$this->prefix . $name]); |
126
|
|
|
break; |
|
|
|
|
127
|
|
|
|
128
|
|
|
case CACHER_XCACHE: |
129
|
|
|
return xcache_isset($this->prefix . $name) && ($this->__get($name) !== null); |
130
|
|
|
break; |
|
|
|
|
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
return false; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
View Code Duplication |
public function __unset($name) { |
|
|
|
|
137
|
|
|
switch (self::$mode) { |
138
|
|
|
case CACHER_NO_CACHE: |
139
|
|
|
unset(self::$data[$this->prefix . $name]); |
140
|
|
|
break; |
141
|
|
|
|
142
|
|
|
case CACHER_XCACHE: |
143
|
|
|
xcache_unset($this->prefix . $name); |
144
|
|
|
break; |
145
|
|
|
} |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
public function unset_by_prefix($prefix_unset = '') { |
149
|
|
|
static $array_clear; |
150
|
|
|
!$array_clear ? $array_clear = function (&$v, $k, $p) { |
151
|
|
|
strpos($k, $p) === 0 ? $v = null : false; |
152
|
|
|
} : false; |
153
|
|
|
|
154
|
|
|
switch (self::$mode) { |
155
|
|
|
case CACHER_NO_CACHE: |
156
|
|
|
// array_walk(self::$data, create_function('&$v,$k,$p', 'if(strpos($k, $p) === 0)$v = NULL;'), $this->prefix.$prefix_unset); |
|
|
|
|
157
|
|
|
array_walk(self::$data, $array_clear, $this->prefix . $prefix_unset); |
158
|
|
|
|
159
|
|
|
return true; |
160
|
|
|
break; |
|
|
|
|
161
|
|
|
|
162
|
|
|
case CACHER_XCACHE: |
163
|
|
|
if (!function_exists('xcache_unset_by_prefix')) { |
164
|
|
|
return false; |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
return xcache_unset_by_prefix($this->prefix . $prefix_unset); |
168
|
|
|
break; |
|
|
|
|
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
return true; |
172
|
|
|
} |
173
|
|
|
// ------------------------------------------------------------------------- |
174
|
|
|
// End of low-level functions |
175
|
|
|
// ------------------------------------------------------------------------- |
176
|
|
|
|
177
|
|
|
protected function make_element_name($args, $diff = 0) { |
178
|
|
|
$num_args = count($args); |
179
|
|
|
|
180
|
|
|
if ($num_args < 1) { |
181
|
|
|
return false; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
$name = ''; |
185
|
|
|
$aName = array(); |
186
|
|
|
for ($i = 0; $i <= $num_args - 1 - $diff; $i++) { |
187
|
|
|
$name .= "[{$args[$i]}]"; |
188
|
|
|
array_unshift($aName, $name); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
return $aName; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
public function array_set() { |
195
|
|
|
$args = func_get_args(); |
196
|
|
|
$name = $this->make_element_name($args, 1); |
197
|
|
|
|
198
|
|
|
if (!$name) { |
199
|
|
|
return null; |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
if ($this->$name[0] === null) { |
203
|
|
|
for ($i = count($name) - 1; $i > 0; $i--) { |
204
|
|
|
$cName = "{$name[$i]}_COUNT"; |
205
|
|
|
$cName1 = "{$name[$i-1]}_COUNT"; |
206
|
|
|
if ($this->$cName1 == null || $i == 1) { |
207
|
|
|
$this->$cName++; |
208
|
|
|
} |
209
|
|
|
} |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
$this->$name[0] = $args[count($args) - 1]; |
213
|
|
|
|
214
|
|
|
return true; |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
public function array_get() { |
218
|
|
|
$name = $this->make_element_name(func_get_args()); |
219
|
|
|
if (!$name) { |
220
|
|
|
return null; |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
return $this->$name[0]; |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
public function array_count() { |
227
|
|
|
$name = $this->make_element_name(func_get_args()); |
228
|
|
|
if (!$name) { |
229
|
|
|
return 0; |
230
|
|
|
} |
231
|
|
|
$cName = "{$name[0]}_COUNT"; |
232
|
|
|
$retVal = $this->$cName; |
233
|
|
|
if (!$retVal) { |
234
|
|
|
$retVal = null; |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
return $retVal; |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
public function array_unset() { |
241
|
|
|
$name = $this->make_element_name(func_get_args()); |
242
|
|
|
|
243
|
|
|
if (!$name) { |
244
|
|
|
return false; |
245
|
|
|
} |
246
|
|
|
$this->unset_by_prefix($name[0]); |
247
|
|
|
|
248
|
|
|
for ($i = 1; $i < count($name); $i++) { |
|
|
|
|
249
|
|
|
$cName = "{$name[$i]}_COUNT"; |
250
|
|
|
$cName1 = "{$name[$i-1]}_COUNT"; |
251
|
|
|
|
252
|
|
|
if ($i == 1 || $this->$cName1 === null) { |
253
|
|
|
$this->$cName--; |
254
|
|
|
if ($this->$cName <= 0) { |
255
|
|
|
unset($this->$cName); |
256
|
|
|
} |
257
|
|
|
} |
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
return true; |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
public function dumpData() { |
264
|
|
|
switch (self::$mode) { |
265
|
|
|
case CACHER_NO_CACHE: |
266
|
|
|
return dump(self::$data, $this->prefix); |
267
|
|
|
break; |
|
|
|
|
268
|
|
|
|
269
|
|
|
default: |
270
|
|
|
return false; |
271
|
|
|
break; |
|
|
|
|
272
|
|
|
} |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
public function reset() { |
276
|
|
|
$this->unset_by_prefix(); |
277
|
|
|
|
278
|
|
|
$this->_INITIALIZED = false; |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
public function init($reInit = false) { |
|
|
|
|
282
|
|
|
$this->_INITIALIZED = true; |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
public function isInitialized() { |
286
|
|
|
return $this->_INITIALIZED; |
287
|
|
|
} |
288
|
|
|
} |
289
|
|
|
|
290
|
|
|
|
291
|
|
|
|
292
|
|
|
|
293
|
|
|
|
294
|
|
|
|
295
|
|
|
|
296
|
|
|
|
297
|
|
|
|
298
|
|
|
|
299
|
|
|
///* |
|
|
|
|
300
|
|
|
//New test metaclass for handling DB table caching |
301
|
|
|
//*/ |
302
|
|
|
// |
303
|
|
|
//class class_db_cache extends classCache |
304
|
|
|
//{ |
305
|
|
|
// protected $tables = array( |
306
|
|
|
// 'users' => array('name' => 'users', 'id' => 'id', 'index' => 'users_INDEX', 'count' => 'users_COUNT', 'lock' => 'users_LOCK', 'callback' => 'cb_users', 'ttl' => 0), |
307
|
|
|
// 'config' => array('name' => 'config', 'id' => 'config_name', 'index' => 'config_INDEX', 'count' => 'config_COUNT', 'lock' => 'config_LOCK', 'callback' => 'cb_config', 'ttl' => 0), |
308
|
|
|
// ); |
309
|
|
|
// |
310
|
|
|
// public function __construct($gamePrefix = 'sn_') |
311
|
|
|
// { |
312
|
|
|
// parent::__construct("{$gamePrefix}dbcache_"); |
313
|
|
|
// } |
314
|
|
|
// |
315
|
|
|
// public function cache_add($table_name = 'table', $id_field = 'id', $ttl = 0, $force_load = false) |
316
|
|
|
// { |
317
|
|
|
// $table['name'] = $table_name; |
318
|
|
|
// $table['id'] = $id_field; |
319
|
|
|
// $table['index'] = "{$table_name}_INDEX"; |
320
|
|
|
// $table['count'] = "{$table_name}_COUNT"; |
321
|
|
|
// $table['lock'] = "{$table_name}_LOCK"; |
322
|
|
|
// $table['callback'] = "cb_{$table_name}"; |
323
|
|
|
// $table['ttl'] = $ttl; |
324
|
|
|
// |
325
|
|
|
// $this->tables[$table_name] = $table; |
326
|
|
|
// // here we can load table data from DB - fields and indexes |
327
|
|
|
// // $force_reload would show should we need to reload table data from DB |
328
|
|
|
// } |
329
|
|
|
// |
330
|
|
|
// // multilock |
331
|
|
|
// protected function table_lock($table_name, $wait_if_locked = false, $lock = NULL) |
332
|
|
|
// { |
333
|
|
|
// $lock_field_name = $this->tables['$table_name']['lock']; |
334
|
|
|
// |
335
|
|
|
// $lock_wait_start = microtime(true); |
336
|
|
|
// while($wait_if_locked && !$this->$lock_field_name && (microtime(true) - $lock_wait_start <= CACHER_LOCK_WAIT)) |
337
|
|
|
// { |
338
|
|
|
// usleep(mt_rand(100, classCache::CACHER_LOCK_SLEEP)); |
339
|
|
|
// } |
340
|
|
|
// |
341
|
|
|
// $result = (!$this->$lock_field_name) XOR ($lock === NULL); |
342
|
|
|
// if($result && $lock) |
343
|
|
|
// { |
344
|
|
|
// $this->$lock_field_name = $lock; |
345
|
|
|
// } |
346
|
|
|
// |
347
|
|
|
// return $result; |
348
|
|
|
// } |
349
|
|
|
// |
350
|
|
|
// |
351
|
|
|
// /* |
352
|
|
|
// Magic start here. __call magic method will transform name of call to table name and handle all caching & db-related stuff |
353
|
|
|
// If there is such row in cache it will be returned. Otherwise it will read from DB, cached and returned |
354
|
|
|
// I.e. class_db_cache->table_name() call mean that all request will be done with records (cached or DB) in `table_name` table |
355
|
|
|
// __call interpets last argument as optional boolean parameter $force. |
356
|
|
|
// In read operations $force === true will tell cacher not to use cached data but load records from DB |
357
|
|
|
// In write operations $force === true will tell cacher immidiatly store new data to DB not relating on internal mechanics |
358
|
|
|
// |
359
|
|
|
// __call have several forms |
360
|
|
|
// |
361
|
|
|
// Form 1: |
362
|
|
|
// __call($id, [$force]) - "SELECT * FROM {table} WHERE id_field = $id" |
363
|
|
|
// |
364
|
|
|
// Form 2: (not implemented yet) |
365
|
|
|
// __call('get', $condition, [$force]) - "SELECT * FROM {table} WHERE $condition" |
366
|
|
|
// |
367
|
|
|
// Form 3: (not implemented yet) |
368
|
|
|
// __call('set', $data, [$condition], [$force]) - "UPDATE {table} SET $row = $data WHERE $condition" |
369
|
|
|
// |
370
|
|
|
// Form 4: (not implemented yet) |
371
|
|
|
// __call('add', $data, [$condition], [$force]) - "UPDATE {table} SET $row = $row + $data WHERE $condition" |
372
|
|
|
// */ |
373
|
|
|
// |
374
|
|
|
// public function __call($name, $arguments) |
375
|
|
|
// { |
376
|
|
|
// $main_argument = $arguments[0]; |
377
|
|
|
// |
378
|
|
|
// switch($main_argument) |
379
|
|
|
// { |
380
|
|
|
// case 'get': |
381
|
|
|
// // it might be SELECT |
382
|
|
|
// break; |
383
|
|
|
// |
384
|
|
|
// case 'set': |
385
|
|
|
// // it might be UPDATE |
386
|
|
|
// break; |
387
|
|
|
// |
388
|
|
|
// default: |
389
|
|
|
// // it might be SELECT * FROM {table} WHERE id = $main_argument; |
390
|
|
|
// return $this->get_item($name, $main_argument, $arguments[1]); |
391
|
|
|
// break; |
392
|
|
|
// } |
393
|
|
|
// } |
394
|
|
|
// |
395
|
|
|
// public function get_item($table_name, $id, $force_reload = false) |
396
|
|
|
// { |
397
|
|
|
// $internal_name = "{$table_name}_{$id}"; |
398
|
|
|
// |
399
|
|
|
// if(isset($this->$internal_name) && !$force_reload) |
400
|
|
|
// { |
401
|
|
|
// // pdump("{$id} - returning stored data"); |
402
|
|
|
// |
403
|
|
|
// return $this->$internal_name; |
404
|
|
|
// } |
405
|
|
|
// else |
406
|
|
|
// { |
407
|
|
|
// // pdump("{$id} - asking DB"); |
408
|
|
|
// |
409
|
|
|
// return $this->db_loadItem($table_name, $id); |
410
|
|
|
// } |
411
|
|
|
// } |
412
|
|
|
// |
413
|
|
|
// public function db_loadItem($table_name, $id) |
414
|
|
|
// { |
415
|
|
|
// // If no table_name or no index - there is no such element |
416
|
|
|
// if(!$id && !$table_name) |
417
|
|
|
// { |
418
|
|
|
// return NULL; |
419
|
|
|
// } |
420
|
|
|
// |
421
|
|
|
// $result = $this->db_loadItems($table_name, '*', "`{$this->tables[$table_name]['id']}` = '{$id}'", 1); |
422
|
|
|
// if($result) |
423
|
|
|
// { |
424
|
|
|
// return $result[$id]; |
425
|
|
|
// } |
426
|
|
|
// else |
427
|
|
|
// { |
428
|
|
|
// $this->del_item($table_name, $id); |
429
|
|
|
// return NULL; |
430
|
|
|
// } |
431
|
|
|
// } |
432
|
|
|
// |
433
|
|
|
// public function db_loadItems($table_name, $fields = '*', $condition = '', $limits = '') |
434
|
|
|
// { |
435
|
|
|
// if(!$fields) |
436
|
|
|
// { |
437
|
|
|
// $fields = '*'; |
438
|
|
|
// } |
439
|
|
|
// |
440
|
|
|
// if($condition) |
441
|
|
|
// { |
442
|
|
|
// $condition = " WHERE {$condition}"; |
443
|
|
|
// } |
444
|
|
|
// |
445
|
|
|
// if($limits) |
446
|
|
|
// { |
447
|
|
|
// $limits = " LIMIT {$limits}"; |
448
|
|
|
// } |
449
|
|
|
// |
450
|
|
|
// $query = doquery("SELECT {$fields} FROM `{{{$table_name}}}`{$condition}{$limits};"); |
451
|
|
|
// |
452
|
|
|
// $table = $this->tables[$table_name]; |
453
|
|
|
// |
454
|
|
|
// $index = $this->$table['index']; |
455
|
|
|
// $count = $this->$table['count']; |
456
|
|
|
// |
457
|
|
|
// $result = NULL; |
458
|
|
|
// |
459
|
|
|
// while ( $row = db_fetch($query) ) |
460
|
|
|
// { |
461
|
|
|
// /* |
462
|
|
|
// foreach($row as $index => &$value) |
463
|
|
|
// { |
464
|
|
|
// if(is_numeric($value)) |
465
|
|
|
// { |
466
|
|
|
// $value = floatval($value); |
467
|
|
|
// |
468
|
|
|
// //if((double)intval($value) === $value) |
469
|
|
|
// //{ |
470
|
|
|
// // $value = intval($value); |
471
|
|
|
// //} |
472
|
|
|
// } |
473
|
|
|
// } |
474
|
|
|
// */ |
475
|
|
|
// |
476
|
|
|
// $item_id = $row[$table['id']]; |
477
|
|
|
// $item_name = "{$table['name']}_{$item_id}"; |
478
|
|
|
// if(!isset($this->$item_name)) |
479
|
|
|
// { |
480
|
|
|
// $count++; |
481
|
|
|
// } |
482
|
|
|
// |
483
|
|
|
// // Loading element to cache |
484
|
|
|
// $this->$item_name = $row; |
485
|
|
|
// // Also loading element to returning set |
486
|
|
|
// $result[$item_id] = $row; |
487
|
|
|
// |
488
|
|
|
// // Internal work |
489
|
|
|
// // Indexing element for fast search |
490
|
|
|
// $index[$item_id] = true; |
491
|
|
|
// } |
492
|
|
|
// |
493
|
|
|
// if($result) |
494
|
|
|
// { |
495
|
|
|
// $this->$table['index'] = $index; |
496
|
|
|
// $this->$table['count'] = $count; |
497
|
|
|
// } |
498
|
|
|
// |
499
|
|
|
// return $result; |
500
|
|
|
// } |
501
|
|
|
// |
502
|
|
|
// public function db_loadAll($table_name) |
503
|
|
|
// { |
504
|
|
|
// $this->unset_by_prefix("{$table_name}_"); |
505
|
|
|
// $this->db_loadItems($table_name); |
506
|
|
|
// } |
507
|
|
|
// |
508
|
|
|
// public function del_item($table_name, $id, $force_db_remove = false) |
509
|
|
|
// { |
510
|
|
|
// $internal_name = "{$table_name}_{$id}"; |
511
|
|
|
// |
512
|
|
|
// if(isset($this->$internal_name)) |
513
|
|
|
// { |
514
|
|
|
// $table = $this->tables[$table_name]; |
515
|
|
|
// |
516
|
|
|
// $index = $this->$table['index']; |
517
|
|
|
// unset($index[$id]); |
518
|
|
|
// $this->$table['index'] = $index; |
519
|
|
|
// |
520
|
|
|
// $this->$table['count']--; |
521
|
|
|
// } |
522
|
|
|
// |
523
|
|
|
// if($force_db_remove) |
524
|
|
|
// { |
525
|
|
|
// doDelete("DELETE FROM {{{$table_name}}} WHERE `{$table['id']}` = '{$id}';"); |
526
|
|
|
// } |
527
|
|
|
// } |
528
|
|
|
// |
529
|
|
|
///* |
530
|
|
|
// public function db_saveAll() |
531
|
|
|
// { |
532
|
|
|
// $toSave = array(); |
533
|
|
|
// foreach($defaults as $field => $value) |
534
|
|
|
// { |
535
|
|
|
// $toSave[$field] = NULL; |
536
|
|
|
// } |
537
|
|
|
// |
538
|
|
|
// $this->db_saveItem($toSave); |
539
|
|
|
// } |
540
|
|
|
// |
541
|
|
|
// public function db_saveItem($index, $value = NULL) |
542
|
|
|
// { |
543
|
|
|
// if($index) |
544
|
|
|
// { |
545
|
|
|
// if(!is_array($index)) |
546
|
|
|
// { |
547
|
|
|
// $index = array($index => $value); |
548
|
|
|
// } |
549
|
|
|
// |
550
|
|
|
// foreach($index as $item_name => &$value) |
551
|
|
|
// { |
552
|
|
|
// if($value !== NULL) |
553
|
|
|
// { |
554
|
|
|
// $this->$item_name = $value; |
555
|
|
|
// } |
556
|
|
|
// else |
557
|
|
|
// { |
558
|
|
|
// $value = $this->$item_name; |
559
|
|
|
// } |
560
|
|
|
// |
561
|
|
|
// $qry .= " ('{$item_name}', '{$value}'),"; |
562
|
|
|
// } |
563
|
|
|
// |
564
|
|
|
// $qry = substr($qry, 0, -1); |
565
|
|
|
// $qry = "REPLACE INTO `{{{$this->table_name}}}` (`{$this->sql_index_field}`, `{$this->sql_value_field}`) VALUES {$qry};"; |
566
|
|
|
// doquery($qry); |
567
|
|
|
// }; |
568
|
|
|
// } |
569
|
|
|
//*/ |
570
|
|
|
//} |
571
|
|
|
|
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.