| Total Complexity | 110 |
| Total Lines | 378 |
| Duplicated Lines | 0 % |
| Changes | 2 | ||
| Bugs | 0 | Features | 0 |
Complex classes like XoopsModelWrite often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use XoopsModelWrite, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 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 | $ts = 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 = $ts->stripSlashesGPC($ts->censorString($cleanv)); |
||
| 80 | } else { |
||
| 81 | $cleanv = $ts->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 = $ts->textFilter($cleanv); |
||
| 95 | } |
||
| 96 | $cleanv = $ts->stripSlashesGPC($ts->censorString($cleanv)); |
||
| 97 | } else { |
||
| 98 | $cleanv = $ts->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 = $ts->stripSlashesGPC($ts->censorString($cleanv)); |
||
| 114 | } else { |
||
| 115 | $cleanv = $ts->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 = $ts->textFilter($cleanv); |
||
| 128 | } |
||
| 129 | $cleanv = $ts->stripSlashesGPC($ts->censorString($cleanv)); |
||
| 130 | } else { |
||
| 131 | $cleanv = $ts->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 = $ts->stripSlashesGPC($cleanv); |
||
| 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 = $ts->stripSlashesGPC($cleanv); |
||
| 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 = $ts->stripSlashesGPC($cleanv); |
||
| 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 = $ts->stripSlashesGPC($cleanv); |
||
| 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 = $ts->stripSlashesGPC($cleanv); |
||
| 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(&$ts, '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(&$ts, '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) |
||
| 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 |
||
| 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) |
||
| 407 | } |
||
| 408 | } |
||
| 409 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.