FromStatement::addJoin()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 9.52
c 0
b 0
f 0
cc 3
nc 4
nop 4
1
<?php
2
3
/**
4
 * @author Jared King <[email protected]>
5
 *
6
 * @link http://jaredtking.com
7
 *
8
 * @copyright 2015 Jared King
9
 * @license MIT
10
 */
11
namespace JAQB\Statement;
12
13
class FromStatement extends Statement
14
{
15
    const FROM = 0;
16
    const INSERT = 1;
17
    const UPDATE = 2;
18
    const DELETE = 3;
19
20
    /**
21
     * @var int
22
     */
23
    protected $type;
24
25
    /**
26
     * @var array
27
     */
28
    protected $tables = [];
29
30
    /**
31
     * @var array
32
     */
33
    protected $joins = [];
34
35
    /**
36
     * @param int $type type of table statement
37
     */
38
    public function __construct($type = self::FROM)
39
    {
40
        $this->type = $type;
41
    }
42
43
    /**
44
     * Adds one or more tables to this statement.
45
     * Supported input styles:
46
     * - addTable('Table,Table2')
47
     * - addTable(['Table','Table2']).
48
     *
49
     * @param string|array $tables
50
     *
51
     * @return self
52
     */
53 View Code Duplication
    public function addTable($tables)
54
    {
55
        if (!is_array($tables)) {
56
            $tables = array_map(function ($t) {
57
                return trim($t);
58
            }, explode(',', $tables));
59
        }
60
61
        $this->tables = array_merge($this->tables, $tables);
62
63
        return $this;
64
    }
65
66
    /**
67
     * Adds a join condition to this statement
68
     * Supported input styles:
69
     * - addJoin('Table,Table2')
70
     * - addJoin(['Table','Table2']).
71
     *
72
     * @param string|array $tables table names
73
     * @param string       $on     ON condition
74
     * @param string       $using  USING columns
75
     * @param string       $type   join type, i.e. OUTER JOIN, CROSS JOIN
76
     *
77
     * @return self
78
     */
79
    public function addJoin($tables, $on = null, $using = null, $type = 'JOIN')
80
    {
81
        if (!is_array($tables)) {
82
            $tables = array_map(function ($t) {
83
                return trim($t);
84
            }, explode(',', $tables));
85
        }
86
87
        if ($using !== null) {
88
            $using = array_map(function ($column) {
89
                return trim($column);
90
            }, explode(',', $using));
91
        } else {
92
            $using = [];
93
        }
94
95
        $this->joins[] = [
96
            $type,
97
            $tables,
98
            $on,
99
            $using,
100
        ];
101
102
        return $this;
103
    }
104
105
    /**
106
     * Gets the table(s) associated with this statement.
107
     *
108
     * @return array
109
     */
110
    public function getTables()
111
    {
112
        return $this->tables;
113
    }
114
115
    /**
116
     * Gets the join(s) associated with this statement.
117
     *
118
     * @return array
119
     */
120
    public function getJoins()
121
    {
122
        return $this->joins;
123
    }
124
125
    public function build()
126
    {
127
        $sql = [];
128
129
        // prefix
130
        if ($this->type === self::FROM) {
131
            $sql[] = 'FROM';
132
        } elseif ($this->type === self::UPDATE) {
133
            $sql[] = 'UPDATE';
134
        } elseif ($this->type === self::INSERT) {
135
            $sql[] = 'INSERT INTO';
136
        } elseif ($this->type === self::DELETE) {
137
            $sql[] = 'DELETE FROM';
138
        }
139
140
        // tables
141
        $tables = $this->tables;
142
        foreach ($tables as &$table) {
143
            $table = $this->escapeIdentifier($table);
144
        }
145
146
        if (count($tables) == 0) {
147
            return '';
148
        }
149
150
        $sql[] = implode(',', array_filter($tables));
151
152
        // joins
153
        $sql[] = $this->buildJoins($this->joins);
154
155
        return implode(' ', array_filter($sql));
156
    }
157
158
    /**
159
     * Builds a list of joins.
160
     *
161
     * @param array $joins
162
     *
163
     * @return string
164
     */
165
    private function buildJoins(array $joins)
166
    {
167
        foreach ($joins as &$join) {
168
            // table(s)
169
            foreach ($join[1] as &$table) {
170
                $table = $this->escapeIdentifier($table);
171
            }
172
            $join[1] = implode(', ', array_filter($join[1]));
173
174
            // on clause
175 View Code Duplication
            if ($join[2]) {
176
                $join[2] = 'ON '.$join[2];
177
            } else {
178
                unset($join[2]);
179
            }
180
181
            // using clause
182
            foreach ($join[3] as &$column) {
0 ignored issues
show
Bug introduced by
The expression $join[3] of type string is not traversable.
Loading history...
183
                $column = $this->escapeIdentifier($column);
184
            }
185
            $join[3] = implode(', ', array_filter($join[3]));
186
187 View Code Duplication
            if ($join[3]) {
188
                $join[3] = 'USING ('.$join[3].')';
189
            } else {
190
                unset($join[3]);
191
            }
192
            $join = implode(' ', $join);
193
        }
194
195
        return implode(' ', array_filter($joins));
196
    }
197
}
198