Issues (3083)

htdocs/class/model/write.php (9 issues)

1
<?php
2
/**
3
 * Object write handler class.
4
 *
5
 * You may not change or alter any portion of this comment or credits
6
 * of supporting developers from this source code or any supporting source code
7
 * which is considered copyrighted (c) material of the original comment or credit authors.
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
13
 * @license             GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
14
 * @package             kernel
15
 * @subpackage          model
16
 * @since               2.3.0
17
 * @author              Taiwen Jiang <[email protected]>
18
 */
19
defined('XOOPS_ROOT_PATH') || exit('Restricted access');
20
21
/**
22
 * Object write handler class.
23
 *
24
 * @author Taiwen Jiang <[email protected]>
25
 * @author Simon Roberts <[email protected]>
26
 *
27
 * {@link XoopsModelAbstract}
28
 */
29
class XoopsModelWrite extends XoopsModelAbstract
30
{
31
    /**
32
     * Clean values of all variables of the object for storage.
33
     * also add slashes and quote string wherever needed
34
     *
35
     * CleanVars only contains changed and cleaned variables
36
     * Reference is used for PHP4 compliance
37
     *
38
     * @param $object
39
     *
40
     * @return bool true if successful
41
     * @access public
42
     */
43
    public function cleanVars(&$object)
44
    {
45
        $myts     = \MyTextSanitizer::getInstance();
46
        $errors = array();
47
48
        $vars              = $object->getVars();
49
        $object->cleanVars = array();
50
        foreach ($vars as $k => $v) {
51
            if (!$v['changed']) {
52
                continue;
53
            }
54
            $cleanv = $v['value'];
55
            switch ($v['data_type']) {
56
                case XOBJ_DTYPE_TIMESTAMP:
57
                    $cleanv = !is_string($cleanv) && is_numeric($cleanv) ? date(_DBTIMESTAMPSTRING, $cleanv) : date(_DBTIMESTAMPSTRING, strtotime($cleanv));
58
                    $cleanv = str_replace('\\"', '"', $this->handler->db->quote($cleanv));
59
                    break;
60
                case XOBJ_DTYPE_TIME:
61
                    $cleanv = !is_string($cleanv) && is_numeric($cleanv) ? date(_DBTIMESTRING, $cleanv) : date(_DBTIMESTRING, strtotime($cleanv));
62
                    $cleanv = str_replace('\\"', '"', $this->handler->db->quote($cleanv));
63
                    break;
64
                case XOBJ_DTYPE_DATE:
65
                    $cleanv = !is_string($cleanv) && is_numeric($cleanv) ? date(_DBDATESTRING, $cleanv) : date(_DBDATESTRING, strtotime($cleanv));
66
                    $cleanv = str_replace('\\"', '"', $this->handler->db->quote($cleanv));
67
                    break;
68
                case XOBJ_DTYPE_UNICODE_TXTBOX:
69
                    if ($v['required'] && $cleanv != '0' && $cleanv == '') {
70
                        $errors[] = sprintf(_XOBJ_ERR_REQUIRED, $k);
71
                        continue 2;
72
                    }
73
                    $cleanv = xoops_convert_encode($cleanv);
74
                    if (isset($v['maxlength']) && strlen($cleanv) > (int)$v['maxlength']) {
75
                        $errors[] = sprintf(_XOBJ_ERR_SHORTERTHAN, $k, (int)$v['maxlength']);
76
                        continue 2;
77
                    }
78
                    if (!$v['not_gpc']) {
79
                        $cleanv = $myts->stripSlashesGPC($myts->censorString($cleanv));
0 ignored issues
show
Deprecated Code introduced by
The function MyTextSanitizer::stripSlashesGPC() has been deprecated: as of XOOPS 2.5.11 and will be removed in next XOOPS version ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

79
                        $cleanv = /** @scrutinizer ignore-deprecated */ $myts->stripSlashesGPC($myts->censorString($cleanv));

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
80
                    } else {
81
                        $cleanv = $myts->censorString($cleanv);
82
                    }
83
                    $cleanv = str_replace('\\"', '"', $this->handler->db->quote($cleanv));
84
                    break;
85
86
                case XOBJ_DTYPE_UNICODE_TXTAREA:
87
                    if ($v['required'] && $cleanv != '0' && $cleanv == '') {
88
                        $errors[] = sprintf(_XOBJ_ERR_REQUIRED, $k);
89
                        continue 2;
90
                    }
91
                    $cleanv = xoops_convert_encode($cleanv);
92
                    if (!$v['not_gpc']) {
93
                        if (!empty($vars['dohtml']['value'])) {
94
                            $cleanv = $myts->textFilter($cleanv);
95
                        }
96
                        $cleanv = $myts->stripSlashesGPC($myts->censorString($cleanv));
0 ignored issues
show
Deprecated Code introduced by
The function MyTextSanitizer::stripSlashesGPC() has been deprecated: as of XOOPS 2.5.11 and will be removed in next XOOPS version ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

96
                        $cleanv = /** @scrutinizer ignore-deprecated */ $myts->stripSlashesGPC($myts->censorString($cleanv));

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
97
                    } else {
98
                        $cleanv = $myts->censorString($cleanv);
99
                    }
100
                    $cleanv = str_replace('\\"', '"', $this->handler->db->quote($cleanv));
101
                    break;
102
103
                case XOBJ_DTYPE_TXTBOX:
104
                    if ($v['required'] && $cleanv != '0' && $cleanv == '') {
105
                        $errors[] = sprintf(_XOBJ_ERR_REQUIRED, $k);
106
                        continue 2;
107
                    }
108
                    if (isset($v['maxlength']) && strlen($cleanv) > (int)$v['maxlength']) {
109
                        $errors[] = sprintf(_XOBJ_ERR_SHORTERTHAN, $k, (int)$v['maxlength']);
110
                        continue 2;
111
                    }
112
                    if (!$v['not_gpc']) {
113
                        $cleanv = $myts->stripSlashesGPC($myts->censorString($cleanv));
0 ignored issues
show
Deprecated Code introduced by
The function MyTextSanitizer::stripSlashesGPC() has been deprecated: as of XOOPS 2.5.11 and will be removed in next XOOPS version ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

113
                        $cleanv = /** @scrutinizer ignore-deprecated */ $myts->stripSlashesGPC($myts->censorString($cleanv));

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
114
                    } else {
115
                        $cleanv = $myts->censorString($cleanv);
116
                    }
117
                    $cleanv = str_replace('\\"', '"', $this->handler->db->quote($cleanv));
118
                    break;
119
120
                case XOBJ_DTYPE_TXTAREA:
121
                    if ($v['required'] && $cleanv != '0' && $cleanv == '') {
122
                        $errors[] = sprintf(_XOBJ_ERR_REQUIRED, $k);
123
                        continue 2;
124
                    }
125
                    if (!$v['not_gpc']) {
126
                        if (!empty($vars['dohtml']['value'])) {
127
                            $cleanv = $myts->textFilter($cleanv);
128
                        }
129
                        $cleanv = $myts->stripSlashesGPC($myts->censorString($cleanv));
0 ignored issues
show
Deprecated Code introduced by
The function MyTextSanitizer::stripSlashesGPC() has been deprecated: as of XOOPS 2.5.11 and will be removed in next XOOPS version ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

129
                        $cleanv = /** @scrutinizer ignore-deprecated */ $myts->stripSlashesGPC($myts->censorString($cleanv));

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
130
                    } else {
131
                        $cleanv = $myts->censorString($cleanv);
132
                    }
133
                    $cleanv = str_replace('\\"', '"', $this->handler->db->quote($cleanv));
134
                    break;
135
136
                case XOBJ_DTYPE_SOURCE:
137
                    $cleanv = trim($cleanv);
138
                    if (!$v['not_gpc']) {
139
                        $cleanv = $myts->stripSlashesGPC($cleanv);
0 ignored issues
show
Deprecated Code introduced by
The function MyTextSanitizer::stripSlashesGPC() has been deprecated: as of XOOPS 2.5.11 and will be removed in next XOOPS version ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

139
                        $cleanv = /** @scrutinizer ignore-deprecated */ $myts->stripSlashesGPC($cleanv);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
140
                    } else {
141
                        $cleanv = $cleanv;
142
                    }
143
                    $cleanv = str_replace('\\"', '"', $this->handler->db->quote($cleanv));
144
                    break;
145
                // Should not be used!
146
                case XOBJ_DTYPE_UNICODE_EMAIL:
147
                    $cleanv = trim($cleanv);
148
                    if ($v['required'] && $cleanv == '') {
149
                        $errors[] = sprintf(_XOBJ_ERR_REQUIRED, $k);
150
                        continue 2;
151
                    }
152
                    if (!$v['not_gpc']) {
153
                        $cleanv = $myts->stripSlashesGPC($cleanv);
0 ignored issues
show
Deprecated Code introduced by
The function MyTextSanitizer::stripSlashesGPC() has been deprecated: as of XOOPS 2.5.11 and will be removed in next XOOPS version ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

153
                        $cleanv = /** @scrutinizer ignore-deprecated */ $myts->stripSlashesGPC($cleanv);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
154
                    }
155
                    $cleanv = str_replace('\\"', '"', $this->handler->db->quote(xoops_convert_encode($cleanv)));
156
                    break;
157
158
                case XOBJ_DTYPE_EMAIL:
159
                    $cleanv = trim($cleanv);
160
                    if ($v['required'] && $cleanv == '') {
161
                        $errors[] = sprintf(_XOBJ_ERR_REQUIRED, $k);
162
                        continue 2;
163
                    }
164
                    if ($cleanv != '' && !preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+([\.][a-z0-9-]+)+$/i", $cleanv)) {
165
                        $errors[] = 'Invalid Email';
166
                        continue 2;
167
                    }
168
                    if (!$v['not_gpc']) {
169
                        $cleanv = $myts->stripSlashesGPC($cleanv);
0 ignored issues
show
Deprecated Code introduced by
The function MyTextSanitizer::stripSlashesGPC() has been deprecated: as of XOOPS 2.5.11 and will be removed in next XOOPS version ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

169
                        $cleanv = /** @scrutinizer ignore-deprecated */ $myts->stripSlashesGPC($cleanv);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
170
                    }
171
                    $cleanv = str_replace('\\"', '"', $this->handler->db->quote($cleanv));
172
                    break;
173
174
                // Should not be used!
175
                case XOBJ_DTYPE_UNICODE_URL:
176
                    $cleanv = trim($cleanv);
177
                    if ($v['required'] && $cleanv == '') {
178
                        $errors[] = sprintf(_XOBJ_ERR_REQUIRED, $k);
179
                        continue 2;
180
                    }
181
                    if ($cleanv != '' && !preg_match("/^http[s]*:\/\//i", $cleanv)) {
182
                        $cleanv = XOOPS_PROT . $cleanv;
183
                    }
184
                    if (!$v['not_gpc']) {
185
                        $cleanv = $myts->stripSlashesGPC($cleanv);
0 ignored issues
show
Deprecated Code introduced by
The function MyTextSanitizer::stripSlashesGPC() has been deprecated: as of XOOPS 2.5.11 and will be removed in next XOOPS version ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

185
                        $cleanv = /** @scrutinizer ignore-deprecated */ $myts->stripSlashesGPC($cleanv);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
186
                    }
187
                    $cleanv = str_replace('\\"', '"', $this->handler->db->quote(xoops_convert_encode($cleanv)));
188
                    break;
189
                case XOBJ_DTYPE_URL:
190
                    $cleanv = trim($cleanv);
191
                    if ($v['required'] && $cleanv == '') {
192
                        $errors[] = sprintf(_XOBJ_ERR_REQUIRED, $k);
193
                        continue 2;
194
                    }
195
                    if ($cleanv != '' && !preg_match("/^http[s]*:\/\//i", $cleanv)) {
196
                        $cleanv = XOOPS_PROT . $cleanv;
197
                    }
198
                    if (!$v['not_gpc']) {
199
                        $cleanv = $myts->stripSlashesGPC($cleanv);
0 ignored issues
show
Deprecated Code introduced by
The function MyTextSanitizer::stripSlashesGPC() has been deprecated: as of XOOPS 2.5.11 and will be removed in next XOOPS version ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

199
                        $cleanv = /** @scrutinizer ignore-deprecated */ $myts->stripSlashesGPC($cleanv);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
200
                    }
201
                    $cleanv = str_replace('\\"', '"', $this->handler->db->quote($cleanv));
202
                    break;
203
204
                // Should not be used!
205
                case XOBJ_DTYPE_UNICODE_OTHER:
206
                    $cleanv = str_replace('\\"', '"', $this->handler->db->quote(xoops_convert_encode($cleanv)));
207
                    break;
208
209
                case XOBJ_DTYPE_OTHER:
210
                    $cleanv = str_replace('\\"', '"', $this->handler->db->quote($cleanv));
211
                    break;
212
213
                case XOBJ_DTYPE_INT:
214
                    $cleanv = (int)$cleanv;
215
                    break;
216
217
                case XOBJ_DTYPE_FLOAT:
218
                    $cleanv = (float)$cleanv;
219
                    break;
220
221
                case XOBJ_DTYPE_DECIMAL:
222
                    $cleanv = (float)$cleanv;
223
                    break;
224
225
                // Should not be used!
226
                case XOBJ_DTYPE_UNICODE_ARRAY:
227
                    if (!$v['not_gpc']) {
228
                        $cleanv = array_map(array(&$myts, 'stripSlashesGPC'), $cleanv);
229
                    }
230
                    foreach (array_keys($cleanv) as $key) {
231
                        $cleanv[$key] = str_replace('\\"', '"', addslashes($cleanv[$key]));
232
                    }
233
                    // TODO: Not encoding safe, should try base64_encode -- phppp
234
                    $cleanv = "'" . serialize(array_walk($cleanv, 'xoops_aw_encode')) . "'";
235
                    break;
236
237
                case XOBJ_DTYPE_ARRAY:
238
                    $cleanv = (array)$cleanv;
239
                    if (!$v['not_gpc']) {
240
                        $cleanv = array_map(array(&$myts, 'stripSlashesGPC'), $cleanv);
241
                    }
242
                    // TODO: Not encoding safe, should try base64_encode -- phppp
243
                    $cleanv = $this->handler->db->quote(serialize($cleanv));
244
                    break;
245
246
                case XOBJ_DTYPE_STIME:
247
                case XOBJ_DTYPE_MTIME:
248
                case XOBJ_DTYPE_LTIME:
249
                    $cleanv = !is_string($cleanv) ? (int)$cleanv : strtotime($cleanv);
250
                    break;
251
252
                default:
253
                    $cleanv = str_replace('\\"', '"', $this->handler->db->quote($cleanv));
254
                    break;
255
            }
256
            $object->cleanVars[$k] = $cleanv;
257
        }
258
        if (!empty($errors)) {
259
            $object->setErrors($errors);
260
        }
261
        $object->unsetDirty();
262
263
        return empty($errors) ? true : false;
264
    }
265
266
    /**
267
     * insert an object into the database
268
     *
269
     * @param  object $object {@link XoopsObject} reference to object
270
     * @param  bool   $force  flag to force the query execution despite security settings
271
     * @return mixed  object ID
272
     */
273
    public function insert(&$object, $force = true)
274
    {
275
        if (!$object->isDirty()) {
276
            trigger_error("Data entry is not inserted - the object '" . get_class($object) . "' is not dirty", E_USER_NOTICE);
277
278
            return $object->getVar($this->handler->keyName);
279
        }
280
        if (!$this->cleanVars($object)) {
281
            trigger_error("Insert failed in method 'cleanVars' of object '" . get_class($object) . "'", E_USER_WARNING);
282
283
            return $object->getVar($this->handler->keyName);
284
        }
285
        $queryFunc = empty($force) ? 'query' : 'queryF';
286
287
        if ($object->isNew()) {
288
            $sql = 'INSERT INTO `' . $this->handler->table . '`';
289
            if (!empty($object->cleanVars)) {
290
                $keys = array_keys($object->cleanVars);
291
                $vals = array_values($object->cleanVars);
292
                $sql .= ' (`' . implode('`, `', $keys) . '`) VALUES (' . implode(',', $vals) . ')';
293
            } else {
294
                trigger_error("Data entry is not inserted - no variable is changed in object of '" . get_class($object) . "'", E_USER_NOTICE);
295
296
                return $object->getVar($this->handler->keyName);
297
            }
298
            if (!$result = $this->handler->db->{$queryFunc}($sql)) {
299
                return false;
300
            }
301
            if (!$object->getVar($this->handler->keyName) && $object_id = $this->handler->db->getInsertId()) {
302
                $object->assignVar($this->handler->keyName, $object_id);
303
            }
304
        } elseif (!empty($object->cleanVars)) {
305
            $keys = array();
306
            foreach ($object->cleanVars as $k => $v) {
307
                $keys[] = " `{$k}` = {$v}";
308
            }
309
            $sql = 'UPDATE `' . $this->handler->table . '` SET ' . implode(',', $keys) . ' WHERE `' . $this->handler->keyName . '` = ' . $this->handler->db->quote($object->getVar($this->handler->keyName));
310
            if (!$result = $this->handler->db->{$queryFunc}($sql)) {
311
                return false;
312
            }
313
        }
314
315
        return $object->getVar($this->handler->keyName);
316
    }
317
318
    /**
319
     * delete an object from the database
320
     *
321
     * @param  object $object {@link XoopsObject} reference to the object to delete
322
     * @param  bool   $force
323
     * @return bool   FALSE if failed.
324
     */
325
    public function delete(&$object, $force = false)
326
    {
327
        if (is_array($this->handler->keyName)) {
328
            $clause = array();
329
            $thishandlerkeyNameCount = count($this->handler->keyName);
330
            for ($i = 0; $i < $thishandlerkeyNameCount; ++$i) {
331
                $clause[] = '`' . $this->handler->keyName[$i] . '` = ' . $this->handler->db->quote($object->getVar($this->handler->keyName[$i]));
332
            }
333
            $whereclause = implode(' AND ', $clause);
334
        } else {
335
            $whereclause = '`' . $this->handler->keyName . '` = ' . $this->handler->db->quote($object->getVar($this->handler->keyName));
336
        }
337
        $sql       = 'DELETE FROM `' . $this->handler->table . '` WHERE ' . $whereclause;
338
        $queryFunc = empty($force) ? 'query' : 'queryF';
339
        $result    = $this->handler->db->{$queryFunc}($sql);
340
341
        return empty($result) ? false : true;
342
    }
343
344
    /**
345
     * delete all objects matching the conditions
346
     *
347
     * @param  CriteriaElement|CriteriaCompo $criteria {@link CriteriaElement} with conditions to meet
348
     * @param  bool   $force    force to delete
349
     * @param  bool   $asObject delete in object way: instantiate all objects and delete one by one
350
     * @return bool|int
351
     */
352
    public function deleteAll(CriteriaElement $criteria = null, $force = true, $asObject = false)
353
    {
354
        if ($asObject) {
355
            $objects = $this->handler->getAll($criteria);
356
            $num     = 0;
357
            foreach (array_keys($objects) as $key) {
358
                $num += $this->delete($objects[$key], $force) ? 1 : 0;
359
            }
360
            unset($objects);
361
362
            return $num;
363
        }
364
        $queryFunc = empty($force) ? 'query' : 'queryF';
365
        $sql       = 'DELETE FROM ' . $this->handler->table;
366
        if (!empty($criteria)) {
367
            if (is_subclass_of($criteria, 'CriteriaElement')) {
368
                $sql .= ' ' . $criteria->renderWhere();
369
            } else {
370
                return false;
371
            }
372
        }
373
        if (!$this->handler->db->{$queryFunc}($sql)) {
374
            return false;
375
        }
376
377
        return $this->handler->db->getAffectedRows();
378
    }
379
380
    /**
381
     * Change a field for objects with a certain criteria
382
     *
383
     * @param  string $fieldname  Name of the field
384
     * @param  mixed  $fieldvalue Value to write
385
     * @param  CriteriaElement|CriteriaCompo  $criteria   {@link CriteriaElement}
386
     * @param  bool   $force      force to query
387
     * @return bool
388
     */
389
    public function updateAll($fieldname, $fieldvalue, CriteriaElement $criteria = null, $force = false)
390
    {
391
        $set_clause = "`{$fieldname}` = ";
392
        if (is_numeric($fieldvalue)) {
393
            $set_clause .= $fieldvalue;
394
        } elseif (is_array($fieldvalue)) {
395
            $set_clause .= $this->handler->db->quote(implode(',', $fieldvalue));
396
        } else {
397
            $set_clause .= $this->handler->db->quote($fieldvalue);
398
        }
399
        $sql = 'UPDATE `' . $this->handler->table . '` SET ' . $set_clause;
400
        if (isset($criteria) && \method_exists($criteria, 'renderWhere')) {
401
            $sql .= ' ' . $criteria->renderWhere();
402
        }
403
        $queryFunc = empty($force) ? 'query' : 'queryF';
404
        $result    = $this->handler->db->{$queryFunc}($sql);
405
406
        return empty($result) ? false : true;
407
    }
408
}
409