JoinTrait::outerJoin()   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
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
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(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
179
        /*# string */ $prefix,
0 ignored issues
show
Unused Code introduced by
The parameter $prefix is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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