Passed
Push — main ( 303b6c...b49db2 )
by Sammy
01:47 queued 15s
created

ClauseJoin::processParamTableNames()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 7
nc 5
nop 1
dl 0
loc 16
rs 8.8333
c 0
b 0
f 0
1
<?php
2
3
namespace HexMakina\Crudites\Grammar\Query;
4
5
use HexMakina\Crudites\Crudites;
6
use HexMakina\Crudites\CruditesException;
7
use HexMakina\BlackBox\Database\TableInterface;
8
9
trait ClauseJoin
10
{
11
    protected $joined_tables = [];
12
13
    abstract public function backTick($field, $table_name = null);
14
15
    abstract public function addBinding($field, $value, $table_name, $bind_label = null): string;
16
17
18
    /**
19
     * Adds a joined table to the query.
20
     *
21
     * @param string $join_table_name The name of the table to join.
22
     * @param string $join_table_alias The alias for the joined table.
23
     * @throws \InvalidArgumentException If the alias is already allocated for a different table.
24
     */
25
    public function addJoinedTable($join_table_name, $join_table_alias)
26
    {
27
        if(!isset($this->joined_tables[$join_table_alias])){
28
            $this->joined_tables[$join_table_alias] = $join_table_name;
29
        }
30
        elseif ($this->joined_tables[$join_table_alias] !== $join_table_name){
31
            throw new \InvalidArgumentException(sprintf(__FUNCTION__.'(): ALIAS `%s` ALREADY ALLOCATED FOR TABLE  `%s`', $join_table_alias, $join_table_name));
32
        }
33
    }
34
35
36
    public function join($table_names, $joins, $join_type = '')
37
    {
38
        list($join_table_name,$join_table_alias) = self::processParamTableNames($table_names);
39
40
        if (preg_match('#^(INNER|LEFT|RIGHT|FULL)(\sOUTER)?#i', $join_type) !== 1) {
41
            $join_type = '';
42
        }
43
        $this->addJoinedTable($join_table_name, $join_table_alias);
44
45
        $raw_join = $this->generateJoin($join_type, $join_table_name, $join_table_alias, $joins);
46
        $this->joinRaw($raw_join);
47
48
        return $this;
49
    }
50
51
    public function joinRaw($sql)
52
    {
53
        return $this->addClause('join', $sql);
0 ignored issues
show
Bug introduced by
It seems like addClause() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

53
        return $this->/** @scrutinizer ignore-call */ addClause('join', $sql);
Loading history...
54
    }
55
56
    protected function generateJoin($join_type, $join_table_name, $join_table_alias = null, $join_fields = []): string
57
    {
58
        $join_table_alias ??= $join_table_name;
59
60
        $join_parts = [];
61
        foreach ($join_fields as $join_field) {
62
            $table = array_shift($join_field);
63
            $field = array_shift($join_field);
64
            
65
            if (!isset($table, $field, $join_field[0])) {
66
                throw new \InvalidArgumentException('INVALID_JOIN_FIELDS');
67
            }
68
69
            $right_operand = null;
70
            // 4 join params -> t.f = t.f
71
            if (isset($join_field[1])) {
72
                $right_operand = $this->backTick($join_field[1], $join_field[0]);
73
74
            } 
75
            // 3 join params -> t.f = v
76
            else{ 
77
                $value = $join_field[0];
78
                // join bind label
79
80
                $bind_label = sprintf(':jbl_%s_%s', $join_table_alias, $field);
81
                // vd($bind_label, 'bind_label');
82
                $this->addBinding($field, $value, $join_table_alias, $bind_label);
83
84
                $right_operand = $bind_label;
85
            }
86
      
87
88
            $join_parts[] = sprintf('%s = %s', $this->backTick($field, $table), $right_operand);
89
        }
90
91
        return sprintf('%s JOIN `%s` %s ON %s', $join_type, $join_table_name, $join_table_alias, implode(' AND ', $join_parts));
92
    }
93
94
    /**
95
     * @return mixed[]
96
     */
97
    public function joinedTables(): array
98
    {
99
        return $this->joined_tables;
100
    }
101
102
    /**
103
     * @return mixed[]|string[]
104
     */
105
    private static function processParamTableNames($table_names): array
106
    {
107
        // it's an array with two indexes, all fine
108
        if (is_array($table_names) && isset($table_names[1]) && !isset($table_names[2])) {
109
            return $table_names;
110
        }
111
112
        if (is_array($table_names) && !isset($table_names[1])) {
113
            $table_names = current($table_names);
114
        }
115
116
        if (is_string($table_names)) {
117
            return [$table_names, $table_names];
118
        }
119
120
        throw new \InvalidArgumentException('INVALID_PARAM_TABLE_NAMES');
121
    }
122
}
123