DbTarget::export()   B
last analyzed

Complexity

Conditions 7
Paths 14

Size

Total Lines 34
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 7.2944

Importance

Changes 0
Metric Value
cc 7
eloc 22
nc 14
nop 0
dl 0
loc 34
ccs 18
cts 22
cp 0.8182
crap 7.2944
rs 8.6346
c 0
b 0
f 0
1
<?php
2
/**
3
 * @link https://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license https://www.yiiframework.com/license/
6
 */
7
8
namespace yii\log;
9
10
use yii\base\InvalidConfigException;
11
use yii\db\Connection;
12
use yii\db\Exception;
13
use yii\di\Instance;
14
use yii\helpers\VarDumper;
15
16
/**
17
 * DbTarget stores log messages in a database table.
18
 *
19
 * The database connection is specified by [[db]]. Database schema could be initialized by applying migration:
20
 *
21
 * ```
22
 * yii migrate --migrationPath=@yii/log/migrations/
23
 * ```
24
 *
25
 * If you don't want to use migration and need SQL instead, files for all databases are in migrations directory.
26
 *
27
 * You may change the name of the table used to store the data by setting [[logTable]].
28
 *
29
 * @author Qiang Xue <[email protected]>
30
 * @since 2.0
31
 */
32
class DbTarget extends Target
33
{
34
    /**
35
     * @var Connection|array|string the DB connection object or the application component ID of the DB connection.
36
     * After the DbTarget object is created, if you want to change this property, you should only assign it
37
     * with a DB connection object.
38
     * Starting from version 2.0.2, this can also be a configuration array for creating the object.
39
     */
40
    public $db = 'db';
41
    /**
42
     * @var string name of the DB table to store cache content. Defaults to "log".
43
     */
44
    public $logTable = '{{%log}}';
45
46
47
    /**
48
     * Initializes the DbTarget component.
49
     * This method will initialize the [[db]] property to make sure it refers to a valid DB connection.
50
     * @throws InvalidConfigException if [[db]] is invalid.
51
     */
52 6
    public function init()
53
    {
54 6
        parent::init();
55 6
        $this->db = Instance::ensure($this->db, Connection::className());
0 ignored issues
show
Deprecated Code introduced by
The function yii\base\BaseObject::className() has been deprecated: since 2.0.14. On PHP >=5.5, use `::class` instead. ( Ignorable by Annotation )

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

55
        $this->db = Instance::ensure($this->db, /** @scrutinizer ignore-deprecated */ Connection::className());

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...
56
    }
57
58
    /**
59
     * Stores log messages to DB.
60
     * Starting from version 2.0.14, this method throws LogRuntimeException in case the log can not be exported.
61
     * @throws Exception
62
     * @throws LogRuntimeException
63
     */
64 6
    public function export()
65
    {
66 6
        if ($this->db->getTransaction()) {
67
            // create new database connection, if there is an open transaction
68
            // to ensure insert statement is not affected by a rollback
69 3
            $this->db = clone $this->db;
70
        }
71
72 6
        $tableName = $this->db->quoteTableName($this->logTable);
73 6
        $sql = "INSERT INTO $tableName ([[level]], [[category]], [[log_time]], [[prefix]], [[message]])
74 6
                VALUES (:level, :category, :log_time, :prefix, :message)";
75 6
        $command = $this->db->createCommand($sql);
76 6
        foreach ($this->messages as $message) {
77 6
            list($text, $level, $category, $timestamp) = $message;
78 6
            if (!is_string($text)) {
79
                // exceptions may not be serializable if in the call stack somewhere is a Closure
80
                if ($text instanceof \Exception || $text instanceof \Throwable) {
81
                    $text = (string) $text;
82
                } else {
83
                    $text = VarDumper::export($text);
84
                }
85
            }
86
            if (
87 6
                $command->bindValues([
88 6
                    ':level' => $level,
89 6
                    ':category' => $category,
90 6
                    ':log_time' => $timestamp,
91 6
                    ':prefix' => $this->getMessagePrefix($message),
92 6
                    ':message' => $text,
93 6
                ])->execute() > 0
94
            ) {
95 6
                continue;
96
            }
97
            throw new LogRuntimeException('Unable to export log through database!');
98
        }
99
    }
100
}
101