Completed
Push — master ( 2de20d...d4d19b )
by Marcin
02:35
created

ReplacesBindings::wrapRegex()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Mnabialek\LaravelSqlLogger\Objects\Concerns;
4
5
use DateTime;
6
7
trait ReplacesBindings
8
{
9
    /**
10
     * Replace bindings.
11
     *
12
     * @param string $sql
13
     * @param array $bindings
14
     *
15
     * @return string
16
     */
17
    protected function replaceBindings($sql, array $bindings)
18
    {
19
        $regex = $this->getRegex();
20
21
        foreach ($this->formatBindings($bindings) as $key => $binding) {
22
            $value = is_numeric($binding) ? $binding : "'" . $binding . "'";
23
            $sql = preg_replace($regex, $value, $sql, 1);
24
        }
25
26
        return $sql;
27
    }
28
29
    /**
30
     * Format bindings values.
31
     *
32
     * @param array $bindings
33
     *
34
     * @return array
35
     */
36
    protected function formatBindings($bindings)
37
    {
38
        foreach ($bindings as $key => $binding) {
39
            if ($binding instanceof DateTime) {
40
                $bindings[$key] = $binding->format('Y-m-d H:i:s');
41
            } elseif (is_string($binding)) {
42
                $bindings[$key] = str_replace("'", "\\'", $binding);
43
            }
44
        }
45
46
        return $bindings;
47
    }
48
49
    /**
50
     * Get regex to be used to replace bindings.
51
     * @return string
52
     */
53
    protected function getRegex()
54
    {
55
        return $this->wrapRegex($this->notInsideQuotes('?') . '|' . $this->notInsideQuotes('\:\w+', false));
56
    }
57
58
    /**
59
     * Wrap regex.
60
     *
61
     * @param string $regex
62
     *
63
     * @return string
64
     */
65
    protected function wrapRegex($regex)
66
    {
67
        return '#' . $regex . '#ms';
68
    }
69
70
    /**
71
     * Create partial regex to find given text not inside quotes.
72
     *
73
     * @param string $string
74
     * @param bool $quote
75
     *
76
     * @return string
77
     */
78
    protected function notInsideQuotes($string, $quote = true)
79
    {
80
        if ($quote) {
81
            $string = preg_quote($string);
82
        }
83
84
        return '(?:"[^"]*[^\\\]"(*SKIP)(*F)|' . $string . ')|(?:\'[^\']*[^\\\]\'(*SKIP)(*F)|' . $string . ')';
85
    }
86
}
87