JoinTrait::leftOuterJoin()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
rs 10
nc 1
cc 1
eloc 2
nop 2
1
<?php
2
/**
3
 * Phossa Project
4
 *
5
 * PHP version 5.4
6
 *
7
 * @category  Library
8
 * @package   Phossa2\Query
9
 * @copyright Copyright (c) 2016 phossa.com
10
 * @license   http://mit-license.org/ MIT License
11
 * @link      http://www.phossa.com/
12
 */
13
/*# declare(strict_types=1); */
14
15
namespace Phossa2\Query\Traits\Clause;
16
17
use Phossa2\Query\Interfaces\StatementInterface;
18
use Phossa2\Query\Interfaces\ExpressionInterface;
19
use Phossa2\Query\Interfaces\Clause\JoinInterface;
20
21
/**
22
 * JoinTrait
23
 *
24
 * Implementation of JoinInterface
25
 *
26
 * @package Phossa2\Query
27
 * @author  Hong Zhang <[email protected]>
28
 * @see     JoinInterface
29
 * @version 2.0.0
30
 * @since   2.0.0 added
31
 */
32
trait JoinTrait
33
{
34
    use AbstractTrait;
35
36
    /**
37
     * {@inheritDoc}
38
     */
39
    public function join($secondTable, $onClause = '')
40
    {
41
        return $this->realJoin('INNER JOIN', $secondTable, $onClause);
42
    }
43
44
    /**
45
     * {@inheritDoc}
46
     */
47
    public function leftJoin($secondTable, $onClause = '')
48
    {
49
        return $this->realJoin('LEFT JOIN', $secondTable, $onClause);
50
    }
51
52
    /**
53
     * {@inheritDoc}
54
     */
55
    public function leftOuterJoin($secondTable, $onClause = '')
56
    {
57
        return $this->realJoin('LEFT OUTER JOIN', $secondTable, $onClause);
58
    }
59
60
    /**
61
     * {@inheritDoc}
62
     */
63
    public function rightJoin($secondTable, $onClause = '')
64
    {
65
        return $this->realJoin('RIGHT JOIN', $secondTable, $onClause);
66
    }
67
68
    /**
69
     * {@inheritDoc}
70
     */
71
    public function rightOuterJoin($secondTable, $onClause = '')
72
    {
73
        return $this->realJoin('RIGHT OUTER JOIN', $secondTable, $onClause);
74
    }
75
76
    /**
77
     * {@inheritDoc}
78
     */
79
    public function outerJoin($secondTable, $onClause = '')
80
    {
81
        return $this->realJoin('OUTER JOIN', $secondTable, $onClause);
82
    }
83
84
    /**
85
     * {@inheritDoc}
86
     */
87
    public function crossJoin($secondTable, $onClause = '')
88
    {
89
        return $this->realJoin('CROSS JOIN', $secondTable, $onClause);
90
    }
91
92
    /**
93
     * {@inheritDoc}
94
     */
95
    public function joinRaw(
96
        /*# string */ $joinType,
97
        /*# string */ $rawString,
98
        array $params = []
99
    ) {
100
    
101
        $rawString = $this->positionedParam($rawString, $params);
102
        return $this->realJoin(strtoupper($joinType), $rawString, '', true);
103
    }
104
105
    /**
106
     * The real join
107
     *
108
     * @param  string $joinType
109
     * @param  string|string[]|SelectStatementInterface $secondTable
110
     * @param  string|string[]|ExpressionInterface $onClause
111
     * @param  bool $rawMode
112
     * @return $this
113
     * @access protected
114
     */
115
    protected function realJoin(
116
        /*# string */ $joinType,
117
        $secondTable,
118
        $onClause = '',
119
        /*# bool */ $rawMode = false
120
    ) {
121
        $alias = 0; // no alias
122
        list($secondTable, $alias) = $this->fixJoinTable($secondTable);
123
124
        if ($rawMode || '' === $onClause || $this->isRaw($onClause, false)) {
125
            $rawMode = true;
126
        } else {
127
            $onClause = $this->fixOnClause($onClause);
128
        }
129
        $clause = &$this->getClause('JOIN');
130
        $clause[] = [$rawMode, $joinType, $secondTable, $alias, $onClause];
131
        return $this;
132
    }
133
134
    /**
135
     * Fix join table
136
     *
137
     * @param  string|string[]|SelectStatementInterface $table
138
     * @return array [table, alias]
139
     * @access protected
140
     */
141
    protected function fixJoinTable($table)
142
    {
143
        if (is_array($table)) {
144
            return $table;
145
        } elseif (is_object($table) && $table instanceof StatementInterface) {
146
            return [$table, uniqid()];
147
        } else {
148
            return [$table, 0]; // alias set 0
149
        }
150
    }
151
152
    /**
153
     * Fix 'ON' clause
154
     *
155
     * @param  mixed $onClause
156
     * @return array|ExpressionInterface
157
     * @access protected
158
     */
159
    protected function fixOnClause($onClause)
160
    {
161
        if (is_string($onClause)) {
162
            return [$onClause, '=', $onClause];
163
        } elseif (is_array($onClause) && !isset($onClause[2])) {
164
            return [$onClause[0], '=', $onClause[1]];
165
        } else {
166
            return $onClause;
167
        }
168
    }
169
170
    /**
171
     * Build join
172
     *
173
     * @param  string $prefix
174
     * @param  array $settings
175
     * @return string
176
     * @access protected
177
     */
178 View Code Duplication
    protected function buildJoin(
179
        /*# string */ $prefix,
180
        array $settings
181
    )/*# : string */ {
182
        $string = '';
183
        $clause = &$this->getClause('JOIN');
184
        foreach ($clause as $cls) {
185
            $result = [];
186
            $prefix = $cls[1]; // join type
187
            $result[] = $this->buildJoinTable($cls, $settings); // join table
188
            if (!empty($cls[4])) {
189
                $result[] = $this->buildJoinOn($cls, $settings);
190
            }
191
            $string .= $this->joinClause($prefix, '', $result, $settings);
192
        }
193
        return $string;
194
    }
195
196
    /**
197
     * Build TABLE part
198
     *
199
     * @param  array $cls
200
     * @param  array $settings
201
     * @return string
202
     * @access protected
203
     */
204
    protected function buildJoinTable(array $cls, array $settings)/*# : string */
205
    {
206
        $table = $cls[2];
207
        $alias = $cls[3];
208
        return $this->quoteItem($table, $settings) . $this->quoteAlias($alias, $settings);
209
    }
210
211
    /**
212
     * Build ON part
213
     *
214
     * @param  array $cls
215
     * @param  array $settings
216
     * @return string
217
     * @access protected
218
     */
219
    protected function buildJoinOn(array $cls, array $settings)/*# : string */
220
    {
221
        $res = ['ON'];
222
        $on = $cls[4];
223
        if (is_string($on)) { // ON string
224
            $res[] = $on;
225
        } elseif (is_object($on)) { // ON is an object
226
            $res[] = $this->quoteItem($on, $settings);
227
        } else { // common on
228
            $res[] = $this->quote( // left
229
                $this->getFirstTableAlias($on[0]) . $on[0],
230
                $settings
231
            );
232
            $res[] = $on[1]; // operator
233
            $res[] = $this->quote( // right
234
                $this->getSecondTableAlias($cls, $on[2]) . $on[2],
235
                $settings
236
            );
237
        }
238
        return join(' ', $res);
239
    }
240
241
    /**
242
     * Get first table alias
243
     *
244
     * @param  string $left left part of eq
245
     * @return string
246
     * @access protected
247
     */
248
    protected function getFirstTableAlias(
249
        /*# string */ $left
250
    )/*# : string */ {
251
        if (false !== strpos($left, '.')) { // alias exists
252
            return '';
253
        } else { // prepend first table alias
254
            $tables = &$this->getClause('TABLE');
255
            reset($tables);
256
            $alias = key($tables);
257
            return (is_int($alias) ? $tables[$alias][0] : $alias) . '.';
258
        }
259
    }
260
261
    /**
262
     * Get second table alias
263
     *
264
     * @param  array $cls
265
     * @param  string $right right part of eq
266
     * @return string
267
     * @access protected
268
     */
269
    protected function getSecondTableAlias(
270
        array $cls,
271
        /*# string */ $right
272
    )/*# : string */ {
273
        if (false !== strpos($right, '.')) {
274
            return '';
275
        } else {
276
            $alias = $cls[3];
277
            if (!is_string($alias)) {
278
                $alias = $cls[2];
279
            }
280
            return $alias . '.';
281
        }
282
    }
283
}
284