Completed
Push — master ( 467d47...6f2bb4 )
by Anton
14s
created

From::addJoin()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 0
Metric Value
nc 1
dl 0
loc 12
ccs 8
cts 8
cp 1
c 0
b 0
f 0
cc 1
eloc 8
nop 5
crap 1
rs 9.4285
1
<?php
2
/**
3
 * Bluz Framework Component
4
 *
5
 * @copyright Bluz PHP Team
6
 * @link      https://github.com/bluzphp/framework
7
 */
8
9
declare(strict_types=1);
10
11
namespace Bluz\Db\Query\Traits;
12
13
use Bluz\Proxy\Db;
14
15
/**
16
 * From Trait
17
 *
18
 * Required for:
19
 *  - Select Builder
20
 *  - Delete Builder
21
 *
22
 * @package  Bluz\Db\Query\Traits
23
 * @author   Anton Shevchuk
24
 */
25
trait From
26
{
27
    /**
28
     * <code>
29
     * [
30
     *     'table' => 'users',
31
     *     'alias' => 'u'
32
     * ]
33
     * </code>
34
     *
35
     * @var array
36
     */
37
    protected $from = [];
38
39
    /**
40
     * <code>
41
     * [
42
     *     'u' => [
43
     *         'joinType' => 'inner',
44
     *         'joinTable' => $join,
45
     *         'joinAlias' => $alias,
46
     *         'joinCondition' => $condition
47
     * ]
48
     * </code>
49
     *
50
     * @var array[]
51
     */
52
    protected $join = [];
53
54
    /**
55
     * Set FROM
56
     *
57
     * Create and add a query root corresponding to the table identified by the
58
     * given alias, forming a cartesian product with any existing query roots
59
     *
60
     * <code>
61
     *     $sb = new SelectBuilder();
62
     *     $sb
63
     *         ->select('u.id')
64
     *         ->from('users', 'u')
65
     * </code>
66
     *
67
     * @param  string $from  The table
68
     * @param  string $alias The alias of the table
69
     *
70
     * @return $this
71
     */
72 8
    public function from(string $from, string $alias)
73
    {
74 8
        $this->aliases[] = $alias;
0 ignored issues
show
Bug introduced by
The property aliases does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
75
76 8
        $this->from[] = [
77 8
            'table' => $from,
78 8
            'alias' => $alias
79
        ];
80
81 8
        return $this;
82
    }
83
84
    /**
85
     * Creates and adds a join to the query
86
     *
87
     * Example
88
     * <code>
89
     *     $sb = new Select();
90
     *     $sb
91
     *         ->select('u.name')
92
     *         ->from('users', 'u')
93
     *         ->join('u', 'phone', 'p', 'p.is_primary = 1');
94
     * </code>
95
     *
96
     * @param  string $fromAlias The alias that points to a from clause
97
     * @param  string $join      The table name to join
98
     * @param  string $alias     The alias of the join table
99
     * @param  string $condition The condition for the join
100
     *
101
     * @return $this
102
     */
103 2
    public function join(string $fromAlias, string $join, string $alias, string $condition = null)
104
    {
105 2
        return $this->innerJoin($fromAlias, $join, $alias, $condition);
106
    }
107
108
    /**
109
     * Creates and adds a join to the query
110
     *
111
     * Example
112
     * <code>
113
     *     $sb = new Select();
114
     *     $sb
115
     *         ->select('u.name')
116
     *         ->from('users', 'u')
117
     *         ->innerJoin('u', 'phone', 'p', 'p.is_primary = 1');
118
     * </code>
119
     *
120
     * @param  string $fromAlias The alias that points to a from clause
121
     * @param  string $join      The table name to join
122
     * @param  string $alias     The alias of the join table
123
     * @param  string $condition The condition for the join
124
     *
125
     * @return $this
126
     */
127 2
    public function innerJoin(string $fromAlias, string $join, string $alias, string $condition = null)
128
    {
129 2
        return $this->addJoin('inner', $fromAlias, $join, $alias, $condition);
130
    }
131
132
    /**
133
     * Creates and adds a left join to the query.
134
     *
135
     * Example
136
     * <code>
137
     *     $sb = new Select();
138
     *     $sb
139
     *         ->select('u.name')
140
     *         ->from('users', 'u')
141
     *         ->leftJoin('u', 'phone', 'p', 'p.is_primary = 1');
142
     * </code>
143
     *
144
     * @param  string $fromAlias The alias that points to a from clause
145
     * @param  string $join      The table name to join
146
     * @param  string $alias     The alias of the join table
147
     * @param  string $condition The condition for the join
148
     *
149
     * @return $this
150
     */
151 1
    public function leftJoin(string $fromAlias, string $join, string $alias, string $condition = null)
152
    {
153 1
        return $this->addJoin('left', $fromAlias, $join, $alias, $condition);
154
    }
155
156
    /**
157
     * Creates and adds a right join to the query.
158
     *
159
     * Example
160
     * <code>
161
     *     $sb = new Select();
162
     *     $sb
163
     *         ->select('u.name')
164
     *         ->from('users', 'u')
165
     *         ->rightJoin('u', 'phone', 'p', 'p.is_primary = 1');
166
     * </code>
167
     *
168
     * @param  string $fromAlias The alias that points to a from clause
169
     * @param  string $join      The table name to join
170
     * @param  string $alias     The alias of the join table
171
     * @param  string $condition The condition for the join
172
     *
173
     * @return $this
174
     */
175 1
    public function rightJoin(string $fromAlias, string $join, string $alias, string $condition = null)
176
    {
177 1
        return $this->addJoin('right', $fromAlias, $join, $alias, $condition);
178
    }
179
180
    /**
181
     * addJoin()
182
     *
183
     * @param  string $type      The type of join
184
     * @param  string $fromAlias The alias that points to a from clause
185
     * @param  string $join      The table name to join
186
     * @param  string $alias     The alias of the join table
187
     * @param  string $condition The condition for the join
188
     *
189
     * @return $this
190
     */
191 4
    protected function addJoin(string $type, string $fromAlias, string $join, string $alias, string $condition = null)
192
    {
193 4
        $this->aliases[] = $alias;
194
195 4
        $this->join[$fromAlias][] = [
196 4
            'joinType' => $type,
197 4
            'joinTable' => $join,
198 4
            'joinAlias' => $alias,
199 4
            'joinCondition' => $condition
200
        ];
201 4
        return $this;
202
    }
203
204
    /**
205
     * setFromQueryPart
206
     *
207
     * @param  string $table
208
     *
209
     * @return self
210
     */
211
    protected function setFromQueryPart($table)
212
    {
213
        return $this->from($table, $table);
214
    }
215
216
    /**
217
     * Prepare From query part
218
     *
219
     * @return string
220
     */
221 8
    protected function prepareFrom() : string
222
    {
223 8
        $fromClauses = [];
224
        // Loop through all FROM clauses
225 8
        foreach ($this->from as $from) {
226 8
            $fromClause = Db::quoteIdentifier($from['table']) . ' AS ' . $from['alias']
227 8
                . $this->prepareJoins($from['alias']);
228
229 8
            $fromClauses[$from['alias']] = $fromClause;
230
        }
231
232 8
        return ' FROM ' . implode(', ', $fromClauses);
233
    }
234
235
    /**
236
     * Generate SQL string for JOINs
237
     *
238
     * @param  string $fromAlias The alias of the table
239
     *
240
     * @return string
241
     */
242 8
    protected function prepareJoins($fromAlias) : string
243
    {
244 8
        if (!isset($this->join[$fromAlias])) {
245 8
            return '';
246
        }
247
248 4
        $query = '';
249
250 4
        foreach ($this->join[$fromAlias] as $join) {
251 4
            $query .= ' ' . strtoupper($join['joinType'])
252 4
                . ' JOIN ' . Db::quoteIdentifier($join['joinTable']) . ' AS ' . $join['joinAlias']
253 4
                . ' ON ' . $join['joinCondition'];
254 4
            $query .= $this->prepareJoins($join['joinAlias']);
255
        }
256
257 4
        return $query;
258
    }
259
}
260