Completed
Pull Request — master (#482)
by Richard
17:16 queued 06:22
created

XoopsMySQLDatabase   B

Complexity

Total Complexity 54

Size/Duplication

Total Lines 475
Duplicated Lines 4.21 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 9.79%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 54
lcom 1
cbo 4
dl 20
loc 475
rs 7.0642
c 1
b 0
f 0
ccs 14
cts 143
cp 0.0979

24 Methods

Rating   Name   Duplication   Size   Complexity  
A queryFromFile() 20 20 4
A genId() 0 5 1
A deprecated() 0 13 2
A connect() 0 7 1
A fetchRow() 0 8 2
A fetchArray() 0 9 2
A fetchBoth() 0 9 2
A fetchObject() 0 9 2
A getInsertId() 0 5 1
A getRowsNum() 0 6 1
A getAffectedRows() 0 5 1
A close() 0 5 1
A freeRecordSet() 0 6 1
A error() 0 6 1
A errno() 0 6 1
A quoteString() 0 6 1
A quote() 0 6 1
A escape() 0 7 1
B queryF() 0 28 5
A query() 0 5 1
A getFieldName() 0 12 2
F getFieldType() 0 28 17
A getFieldsNum() 0 6 1
A getServerVersion() 0 9 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like XoopsMySQLDatabase 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 XoopsMySQLDatabase, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * You may not change or alter any portion of this comment or credits
4
 * of supporting developers from this source code or any supporting source code
5
 * which is considered copyrighted (c) material of the original comment or credit authors.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
 */
11
12
/**
13
 * connection to a mysql database - legacy support only
14
 *
15
 * PHP version 5.3
16
 *
17
 * @category   Xoops\Class\Database\MySQLDatabase
18
 * @package    MySQLDatabase
19
 * @author     Kazumi Ono <[email protected]>
20
 * @author     readheadedrod <[email protected]>
21
 * @author     Richard Griffith <[email protected]>
22
 * @copyright  2013 XOOPS Project (http://xoops.org)
23
 * @license    GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
24
 * @version    Release: 2.6
25
 * @link       http://xoops.org
26
 * @since      2.6.0
27
 * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
28
 *
29
 */
30
class XoopsMySQLDatabase extends XoopsDatabase
0 ignored issues
show
Deprecated Code introduced by
The class XoopsDatabase has been deprecated with message: since version 2.6.0 - alpha 3. Switch to doctrine connector.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
31
{
32
33
    /**
34
     * @var object keep track of last result since we need it for getAffectedRows
35
     */
36
    private $lastResult = null;
37
38
    /**
39
     * Database connection
40
     *
41
     * @var resource
42
     */
43
    public $conn;
44
45
    /**
46
     * Database connection
47
     *
48
     * @var resource
49
     */
50
    private $connect = false;
51
52
    /**
53
     * Database connection
54
     *
55
     * @var resource
56
     */
57
    private $selectdb;
58
59
    /**
60
     * Issue a deprecated warning once per session
61
     *
62
     * @return void
63
     */
64 1
    protected function deprecated()
65
    {
66 1
        static $warning_issued = false;
67 1
        if (!$warning_issued) {
68 1
            $warning_issued = true;
69 1
            $stack = debug_backtrace();
70 1
            $frame = $stack[1];
71 1
            Xoops::getInstance()->deprecated(
72
                'Legacy XoopsDB is deprecated since 2.6.0; all calls should be using Doctrine through $xoops->db(). '
73 1
                . 'Called from ' . $frame['function'] . '() in ' . $frame['file'] . ' line '. $frame['line']
74 1
            );
75 1
        }
76 1
    }
77
78
79
    /**
80
     * connect to the database
81
     *
82
     * @param bool $selectdb select the database now?
83
     *
84
     * @return bool successful?
85
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
86
     */
87
    public function connect($selectdb = true)
0 ignored issues
show
Coding Style introduced by
connect uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
88
    {
89
        $this->connect = (is_object($this->conn));
0 ignored issues
show
Documentation Bug introduced by
It seems like is_object($this->conn) of type boolean is incompatible with the declared type resource of property $connect.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
90
        $this->selectdb = $selectdb;
0 ignored issues
show
Documentation Bug introduced by
It seems like $selectdb of type boolean is incompatible with the declared type resource of property $selectdb.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
91
        $this->allowWebChanges = ($_SERVER['REQUEST_METHOD'] !== 'GET');
92
        return $this->connect;
93
    }
94
95
96
    /**
97
     * generate an ID for a new row
98
     *
99
     * This is for compatibility only. Will always return 0, because MySQL supports
100
     * autoincrement for primary keys.
101
     *
102
     * @param string $sequence name of the sequence from which to get the next ID
103
     *
104
     * @return int always 0, because mysql has support for autoincrement
105
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
106
     */
107 1
    public function genId($sequence)
108
    {
109 1
        $this->deprecated();
110 1
        return 0; // will use auto_increment
111
    }
112
113
    /**
114
     * Get a result row as an enumerated array
115
     *
116
     * @param resource $result resource to get result from
117
     *
118
     * @return array
119
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
120
     */
121
    public function fetchRow($result)
122
    {
123
        $this->deprecated();
124
        if (!is_object($result)) {
125
            return null;
126
        }
127
        return $result->fetch(\PDO::FETCH_NUM);
128
    }
129
130
    /**
131
     * Fetch a result row as an associative array
132
     *
133
     * @param resource $result resource to get result from
134
     *
135
     * @return array
136
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
137
     */
138
    public function fetchArray($result)
139
    {
140
        $this->deprecated();
141
142
        if (!is_object($result)) {
143
            return null;
144
        }
145
        return $result->fetch(\PDO::FETCH_ASSOC);
146
    }
147
148
    /**
149
     * Fetch a result row as an associative array
150
     *
151
     * @param resource $result resource to get result from
152
     *
153
     * @return array
154
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
155
     */
156
    public function fetchBoth($result)
157
    {
158
        $this->deprecated();
159
160
        if (!is_object($result)) {
161
            return null;
162
        }
163
        return $result->fetch(\PDO::FETCH_BOTH);
164
    }
165
166
    /**
167
     * Fetch a result row as an object
168
     *
169
     * @param resource $result resource to get result from
170
     *
171
     * @return object|stdClass
172
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
173
     */
174
    public function fetchObject($result)
175
    {
176
        $this->deprecated();
177
178
        if (!is_object($result)) {
179
            return null;
180
        }
181
        return $result->fetch(\PDO::FETCH_OBJ);
182
    }
183
184
    /**
185
     * Get the ID generated from the previous INSERT operation
186
     *
187
     * @return int
188
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
189
     */
190
    public function getInsertId()
191
    {
192
        $this->deprecated();
193
        return $this->conn->lastInsertId();
0 ignored issues
show
Bug introduced by
The method lastInsertId cannot be called on $this->conn (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
194
    }
195
196
    /**
197
     * Get number of rows in result
198
     *
199
     * @param resource $result the resource containing the number of rows
200
     *
201
     * @return int the number of rows to return
202
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
203
     */
204
    public function getRowsNum($result)
205
    {
206
        Xoops::getInstance()->deprecated('getRowsNum is deprecated and not dependable.');
207
        //$this->deprecated();
208
        return $result->rowCount();
0 ignored issues
show
Bug introduced by
The method rowCount cannot be called on $result (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
209
    }
210
211
    /**
212
     * Get number of affected rows
213
     *
214
     * @return int
215
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
216
     */
217
    public function getAffectedRows()
218
    {
219
        $this->deprecated();
220
        return $this->lastResult->rowCount();
221
    }
222
223
    /**
224
     * Close MySQL connection
225
     *
226
     * @return void
227
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
228
     */
229
    public function close()
230
    {
231
        $this->deprecated();
232
        return $this->conn->close();
0 ignored issues
show
Bug introduced by
The method close cannot be called on $this->conn (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
233
    }
234
235
    /**
236
     * will free all memory associated with the result identifier result.
237
     *
238
     * @param resource $result query result
239
     *
240
     * @return bool TRUE on success or FALSE on failure.
241
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
242
     */
243
    public function freeRecordSet($result)
244
    {
245
        $this->deprecated();
246
247
        return $result->closeCursor();
0 ignored issues
show
Bug introduced by
The method closeCursor cannot be called on $result (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
248
    }
249
250
    /**
251
     * Returns the text of the error message from previous MySQL operation
252
     *
253
     * @return bool Returns the error text from the last MySQL function,
254
     * or '' (the empty string) if no error occurred.
255
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
256
     */
257
    public function error()
258
    {
259
        $this->deprecated();
260
261
        return $this->conn->errorInfo();
0 ignored issues
show
Bug introduced by
The method errorInfo cannot be called on $this->conn (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
262
    }
263
264
    /**
265
     * Returns the numerical value of the error message from previous
266
     * MySQL operation
267
     *
268
     * @return int Returns the error number from the last MySQL function
269
     * , or 0 (zero) if no error occurred.
270
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
271
     */
272
    public function errno()
273
    {
274
        $this->deprecated();
275
276
        return $this->conn->errorCode();
0 ignored issues
show
Bug introduced by
The method errorCode cannot be called on $this->conn (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
277
    }
278
279
    /**
280
     * Returns escaped string text with single
281
     * quotes around it to be safely stored in database
282
     *
283
     * @param string $str unescaped string text
284
     *
285
     * @return string escaped string text with single quotes around
286
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
287
     */
288
    public function quoteString($str)
289
    {
290
        $this->deprecated();
291
292
        return $this->quote($str);
0 ignored issues
show
Deprecated Code introduced by
The method XoopsMySQLDatabase::quote() has been deprecated with message: since version 2.6.0 - alpha 3. Switch to doctrine connector.

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

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

Loading history...
293
    }
294
295
    /**
296
     * Quotes a string for use in a query.
297
     *
298
     * @param string $string string to quote
299
     *
300
     * @return string
301
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
302
     */
303
    public function quote($string)
304
    {
305
        $this->deprecated();
306
307
        return  $this->conn->quote($string);
0 ignored issues
show
Bug introduced by
The method quote cannot be called on $this->conn (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
308
    }
309
310
    /**
311
     * Escapes a string for use in a query. Does not add quotes.
312
     *
313
     * @param string $string string to escape
314
     *
315
     * @return string
316
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
317
     */
318
    public function escape($string)
319
    {
320
        $this->deprecated();
321
322
        $string = $this->quote($string);
0 ignored issues
show
Deprecated Code introduced by
The method XoopsMySQLDatabase::quote() has been deprecated with message: since version 2.6.0 - alpha 3. Switch to doctrine connector.

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

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

Loading history...
323
        return substr($string, 1, -1);
324
    }
325
326
    /**
327
     * perform a query on the database
328
     *
329
     * @param string $sql   a valid MySQL query
330
     * @param int    $limit number of records to return
331
     * @param int    $start offset of first record to return
332
     *
333
     * @return bool|resource query result or FALSE if successful
334
     * or TRUE if successful and no result
335
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
336
     */
337
    public function queryF($sql, $limit = 0, $start = 0)
338
    {
339
        $this->deprecated();
340
341
        if (!empty($limit)) {
342
            if (empty($start)) {
343
                $start = 0;
344
            }
345
            $sql = $sql . ' LIMIT ' . (int) $start . ', ' . (int) $limit;
346
        }
347
        $events = \Xoops::getInstance()->events();
348
        $events->triggerEvent('core.database.query.start');
349
        try {
350
            $result = $this->conn->query($sql);
0 ignored issues
show
Bug introduced by
The method query cannot be called on $this->conn (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
351
        } catch (Exception $e) {
352
            $result=false;
353
        }
354
        $this->lastResult = $result;
355
        $events->triggerEvent('core.database.query.end');
356
357
        if ($result) {
358
            $events->triggerEvent('core.database.query.success', (array($sql)));
359
            return $result;
360
        } else {
361
            $events->triggerEvent('core.database.query.failure', (array($sql, $this)));
362
            return false;
363
        }
364
    }
365
366
    /**
367
     * perform a query
368
     *
369
     * This method is empty and does nothing! It should therefore only be
370
     * used if nothing is exactly what you want done! ;-)
371
     *
372
     * @param string $sql   a valid MySQL query
373
     * @param int    $limit number of records to return
374
     * @param int    $start offset of first record to return
375
     *
376
     * @return this returns nothing
377
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
378
     */
379
    public function query($sql, $limit = 0, $start = 0)
380
    {
381
        $this->deprecated();
382
383
    }
384
385
    /**
386
     * perform queries from SQL dump file in a batch
387
     *
388
     * @param string $file file path to an SQL dump file
389
     *
390
     * @return bool FALSE if failed reading SQL file or TRUE
391
     * if the file has been read and queries executed
392
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
393
     */
394 View Code Duplication
    public function queryFromFile($file)
395
    {
396
        $this->deprecated();
397
398
        if (false !== ($fp = fopen($file, 'r'))) {
399
            $sql_queries = trim(fread($fp, filesize($file)));
400
            SqlUtility::splitMySqlFile($pieces, $sql_queries);
401
            foreach ($pieces as $query) {
402
                // [0] contains the prefixed query
403
                // [4] contains unprefixed table name
404
                $prefixed_query
405
                    = SqlUtility::prefixQuery(trim($query), $this->prefix());
0 ignored issues
show
Deprecated Code introduced by
The method XoopsDatabase::prefix() has been deprecated with message: since version 2.6.0 - alpha 3. Switch to doctrine connector.

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

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

Loading history...
406
                if ($prefixed_query != false) {
407
                    $this->query($prefixed_query[0]);
0 ignored issues
show
Deprecated Code introduced by
The method XoopsMySQLDatabase::query() has been deprecated with message: since version 2.6.0 - alpha 3. Switch to doctrine connector.

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

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

Loading history...
408
                }
409
            }
410
            return true;
411
        }
412
        return false;
413
    }
414
415
    /**
416
     * Get field name
417
     *
418
     * @param resource $result query result
419
     * @param int      $offset numerical field index
420
     *
421
     * @return string
422
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
423
     */
424
    public function getFieldName($result, $offset)
425
    {
426
        $this->deprecated();
427
428
        try {
429
            $temp = $result->getColumnMeta($offset);
0 ignored issues
show
Bug introduced by
The method getColumnMeta cannot be called on $result (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
430
            return $temp['name'];
431
        } catch (PDOException $e) {
432
            return null;
433
        }
434
435
    }
436
437
    /**
438
     * Get field type
439
     *
440
     * @param resource $result query result
441
     * @param int      $offset numerical field index
442
     *
443
     * @return string
444
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
445
     */
446
    public function getFieldType($result, $offset)
447
    {
448
        $this->deprecated();
449
450
        try {
451
            $temp = ($result->getColumnMeta($offset));
0 ignored issues
show
Bug introduced by
The method getColumnMeta cannot be called on $result (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
452
            $t = $temp['native_type'];
453
454
            $temp = (string)(
455
                ((($t === 'STRING') || ($t === 'VAR_STRING') ) ? 'string' : '' ) .
456
                ( (in_array($t, array('TINY', 'SHORT', 'LONG', 'LONGLONG', 'INT24'))) ? 'int' : '' ) .
457
                ( (in_array($t, array('FLOAT', 'DOUBLE', 'DECIMAL', 'NEWDECIMAL'))) ? 'real' : '' ) .
458
                ( ($t === 'TIMESTAMP') ? 'timestamp' : '' ) .
459
                ( ($t === 'YEAR') ? 'year' : '') .
460
                ( (($t === 'DATE') || ($t === 'NEWDATE') ) ? 'date' : '' ) .
461
                ( ($t === 'TIME') ? 'time' : '' ) .
462
                ( ($t === 'SET') ? 'set' : '' ) .
463
                ( ($t === 'ENUM') ? 'enum' : '' ) .
464
                ( ($t === 'GEOMETRY') ? 'geometry' : '' ) .
465
                ( ($t === 'DATETIME') ? 'datetime' : '' ) .
466
                ( (in_array($t, array('TINY_BLOB', 'BLOB', 'MEDIUM_BLOB', 'LONG_BLOB' ))) ? 'blob' : '' ) .
467
                ( ($t === 'NULL') ? 'null' : '' )
468
            );
469
            return $temp;
470
        } catch (PDOException $e) {
471
            return null;
472
        }
473
    }
474
475
    /**
476
     * Get number of fields in result
477
     *
478
     * @param resource $result query result
479
     *
480
     * @return int
481
     * @deprecated since version 2.6.0 - alpha 3. Switch to doctrine connector.
482
     */
483
    public function getFieldsNum($result)
484
    {
485
        $this->deprecated();
486
487
        return $result->columnCount();
0 ignored issues
show
Bug introduced by
The method columnCount cannot be called on $result (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
488
    }
489
490
    /**
491
     * getServerVersion get version of the mysql server
492
     *
493
     * @return string
494
     */
495
    public function getServerVersion()
496
    {
497
        $conn = \Xoops::getInstance()->db()->getWrappedConnection();
498
        $version = '(not available)';
499
        if ($conn instanceof \PDO) {
500
            $version = $conn->getAttribute(\PDO::ATTR_SERVER_VERSION);
501
        }
502
        return $version;
503
    }
504
}
505