Issues (148)

src/Db/Query/Traits/From.php (2 issues)

1
<?php
2
3
/**
4
 * Bluz Framework Component
5
 *
6
 * @copyright Bluz PHP Team
7
 * @link      https://github.com/bluzphp/framework
8
 */
9
10
declare(strict_types=1);
11
12
namespace Bluz\Db\Query\Traits;
13
14
use Bluz\Proxy\Db;
15
16
/**
17
 * From Trait
18
 *
19
 * Required for:
20
 *  - Select Builder
21
 *  - Delete Builder
22
 *
23
 * @package  Bluz\Db\Query\Traits
24
 * @author   Anton Shevchuk
25
 */
26
trait From
27
{
28
    /**
29
     * <code>
30
     * [
31
     *     'table' => 'users',
32
     *     'alias' => 'u'
33
     * ]
34
     * </code>
35
     *
36
     * @var array
37
     */
38
    protected $from = [];
39
40
    /**
41
     * <code>
42
     * [
43
     *     'u' => [
44
     *         'joinType' => 'inner',
45
     *         'joinTable' => $join,
46
     *         'joinAlias' => $alias,
47
     *         'joinCondition' => $condition
48
     * ]
49
     * </code>
50
     *
51
     * @var array[]
52
     */
53
    protected $join = [];
54
55
    /**
56
     * Set FROM
57
     *
58
     * Create and add a query root corresponding to the table identified by the
59
     * given alias, forming a cartesian product with any existing query roots
60
     *
61
     * <code>
62
     *     $sb = new SelectBuilder();
63
     *     $sb
64
     *         ->select('u.id')
65
     *         ->from('users', 'u')
66
     * </code>
67
     *
68
     * @param  string $from  The table
69
     * @param  string $alias The alias of the table
70
     *
71
     * @return $this
72
     */
73 8
    public function from(string $from, string $alias): self
74
    {
75 8
        $this->aliases[] = $alias;
0 ignored issues
show
Bug Best Practice introduced by
The property aliases does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
76
77 8
        $this->from[] = [
78 8
            'table' => $from,
79 8
            'alias' => $alias
80
        ];
81
82 8
        return $this;
83
    }
84
85
    /**
86
     * Creates and adds a join to the query
87
     *
88
     * Example
89
     * <code>
90
     *     $sb = new Select();
91
     *     $sb
92
     *         ->select('u.name')
93
     *         ->from('users', 'u')
94
     *         ->join('u', 'phone', 'p', 'p.is_primary = 1');
95
     * </code>
96
     *
97
     * @param  string $fromAlias The alias that points to a from clause
98
     * @param  string $join      The table name to join
99
     * @param  string $alias     The alias of the join table
100
     * @param  string $condition The condition for the join
101
     *
102
     * @return $this
103
     */
104 2
    public function join(string $fromAlias, string $join, string $alias, string $condition = null): self
105
    {
106 2
        return $this->innerJoin($fromAlias, $join, $alias, $condition);
107
    }
108
109
    /**
110
     * Creates and adds a join to the query
111
     *
112
     * Example
113
     * <code>
114
     *     $sb = new Select();
115
     *     $sb
116
     *         ->select('u.name')
117
     *         ->from('users', 'u')
118
     *         ->innerJoin('u', 'phone', 'p', 'p.is_primary = 1');
119
     * </code>
120
     *
121
     * @param  string $fromAlias The alias that points to a from clause
122
     * @param  string $join      The table name to join
123
     * @param  string $alias     The alias of the join table
124
     * @param  string $condition The condition for the join
125
     *
126
     * @return $this
127
     */
128 2
    public function innerJoin(string $fromAlias, string $join, string $alias, string $condition = null): self
129
    {
130 2
        return $this->addJoin('inner', $fromAlias, $join, $alias, $condition);
131
    }
132
133
    /**
134
     * Creates and adds a left join to the query.
135
     *
136
     * Example
137
     * <code>
138
     *     $sb = new Select();
139
     *     $sb
140
     *         ->select('u.name')
141
     *         ->from('users', 'u')
142
     *         ->leftJoin('u', 'phone', 'p', 'p.is_primary = 1');
143
     * </code>
144
     *
145
     * @param  string $fromAlias The alias that points to a from clause
146
     * @param  string $join      The table name to join
147
     * @param  string $alias     The alias of the join table
148
     * @param  string $condition The condition for the join
149
     *
150
     * @return $this
151
     */
152 1
    public function leftJoin(string $fromAlias, string $join, string $alias, string $condition = null): self
153
    {
154 1
        return $this->addJoin('left', $fromAlias, $join, $alias, $condition);
155
    }
156
157
    /**
158
     * Creates and adds a right join to the query.
159
     *
160
     * Example
161
     * <code>
162
     *     $sb = new Select();
163
     *     $sb
164
     *         ->select('u.name')
165
     *         ->from('users', 'u')
166
     *         ->rightJoin('u', 'phone', 'p', 'p.is_primary = 1');
167
     * </code>
168
     *
169
     * @param  string $fromAlias The alias that points to a from clause
170
     * @param  string $join      The table name to join
171
     * @param  string $alias     The alias of the join table
172
     * @param  string $condition The condition for the join
173
     *
174
     * @return $this
175
     */
176 1
    public function rightJoin(string $fromAlias, string $join, string $alias, string $condition = null): self
177
    {
178 1
        return $this->addJoin('right', $fromAlias, $join, $alias, $condition);
179
    }
180
181
    /**
182
     * addJoin()
183
     *
184
     * @param  string $type      The type of join
185
     * @param  string $fromAlias The alias that points to a from clause
186
     * @param  string $join      The table name to join
187
     * @param  string $alias     The alias of the join table
188
     * @param  string $condition The condition for the join
189
     *
190
     * @return $this
191
     */
192 4
    protected function addJoin(
193
        string $type,
194
        string $fromAlias,
195
        string $join,
196
        string $alias,
197
        string $condition = null
198
    ): self {
199 4
        $this->aliases[] = $alias;
0 ignored issues
show
Bug Best Practice introduced by
The property aliases does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
200
201 4
        $this->join[$fromAlias][] = [
202 4
            'joinType' => $type,
203 4
            'joinTable' => $join,
204 4
            'joinAlias' => $alias,
205 4
            'joinCondition' => $condition
206
        ];
207 4
        return $this;
208
    }
209
210
    /**
211
     * setFromQueryPart
212
     *
213
     * @param  string $table
214
     *
215
     * @return self
216
     */
217
    protected function setFromQueryPart($table): self
218
    {
219
        return $this->from($table, $table);
220
    }
221
222
    /**
223
     * Prepare From query part
224
     *
225
     * @return string
226
     */
227 8
    protected function prepareFrom(): string
228
    {
229 8
        $fromClauses = [];
230
        // Loop through all FROM clauses
231 8
        foreach ($this->from as $from) {
232 8
            $fromClause = Db::quoteIdentifier($from['table']) . ' AS ' . Db::quoteIdentifier($from['alias'])
233 8
                . $this->prepareJoins($from['alias']);
234
235 8
            $fromClauses[$from['alias']] = $fromClause;
236
        }
237
238 8
        return ' FROM ' . implode(', ', $fromClauses);
239
    }
240
241
    /**
242
     * Generate SQL string for JOINs
243
     *
244
     * @param  string $fromAlias The alias of the table
245
     *
246
     * @return string
247
     */
248 8
    protected function prepareJoins($fromAlias): string
249
    {
250 8
        if (!isset($this->join[$fromAlias])) {
251 8
            return '';
252
        }
253
254 4
        $query = '';
255
256 4
        foreach ($this->join[$fromAlias] as $join) {
257 4
            $query .= ' ' . strtoupper($join['joinType'])
258 4
                . ' JOIN ' . Db::quoteIdentifier($join['joinTable']) . ' AS ' . Db::quoteIdentifier($join['joinAlias'])
259 4
                . ' ON ' . $join['joinCondition'];
260 4
            $query .= $this->prepareJoins($join['joinAlias']);
261
        }
262
263 4
        return $query;
264
    }
265
}
266