Passed
Push — main ( 72ed59...7b3af7 )
by Sammy
01:55
created

Query::base()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 1
b 0
f 1
1
<?php
2
3
namespace HexMakina\Crudites\Grammar\Query;
4
5
use HexMakina\BlackBox\Database\QueryInterface;
6
use HexMakina\Crudites\Grammar\Clause\Clause;
7
8
abstract class Query implements QueryInterface
9
{
10
    protected array $bindings = [];
11
    
12
    protected string $table;
13
    protected ?string $alias = null;
14
    
15
    
16
    protected array $clauses = [];
17
    
18
    abstract public function statement(): string;
19
    
20
    /**
21
     * Provides debugging information about the object.
22
     * This method returns an array of object properties and their values,
23
     * excluding properties that are not set.
24
     */
25
    public function __debugInfo(): array
26
    {
27
        $dbg = get_object_vars($this);
28
29
        foreach (array_keys($dbg) as $k) {
30
            if (!isset($dbg[$k])) {
31
                unset($dbg[$k]);
32
            }
33
        }
34
35
        $dbg['statement()'] = $this->statement();
36
37
        
38
        if (empty($this->bindings)) {
39
            unset($dbg['bindings']);
40
        }
41
        else{
42
            $dbg['bindings'] = json_encode($dbg['bindings']);
43
        }
44
45
        return $dbg;
46
    }
47
48
    public function __toString()
49
    {
50
        return $this->statement();
51
    }
52
53
    public function table(): string
54
    {
55
        return $this->table;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->table returns the type string which is incompatible with the return type mandated by HexMakina\BlackBox\Datab...QueryInterface::table() of HexMakina\BlackBox\Database\TableInterface.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
56
    }
57
58
    public function alias(): ?string
59
    {
60
        return $this->alias;
61
    }
62
63
    public function base(): string
64
    {
65
        return $this->alias ?? $this->table;
66
    }
67
68
    public function clause(string $name): ?Clause
69
    {
70
        return $this->clauses[$name] ?? null;
71
    }
72
73
    public function add(Clause $clause): self
74
    {
75
        $this->clauses[$clause->name()] = $clause;
76
        return $this;
77
    }
78
79
    public function set(Clause $clause): self
80
    {
81
        unset($this->clauses[$clause->name()]);
82
        return $this->add($clause);
83
    }
84
85
    //------------------------------------------------------------  PREP::FIELDS
86
    public function tableLabel(string $force = null)
87
    {
88
        return $force ?? $this->tableAlias();
89
    }
90
91
    public function tableAlias($setter = null): string
92
    {
93
        if ($setter !== null) {
94
            $this->alias = $setter;
95
        }
96
97
        return $this->alias ?? $this->table;
98
    }
99
100
    public function bindings(): array
101
    {
102
        if(empty($this->clauses)){
103
            return $this->bindings;
104
        }
105
106
        return array_merge($this->bindings, array_reduce($this->clauses, function ($carry, $clause) {
107
            return array_merge($carry, $clause->bindings());
108
        }, []));
109
    }
110
    
111
    public function addBinding($field, $value, $table_name = null, $bind_label = null): string
112
    {
113
        $bind_label ??= $this->bindLabel($field, $table_name);
114
115
        $this->bindings[$bind_label] = $value;
116
117
        return $bind_label;
118
    }
119
120
    public function bindLabel($field, $table_name = null): string
121
    {
122
        return ':' . $this->tableLabel($table_name) . '_' . $field;
123
    }
124
125
    public function addBindings($assoc_data): array
126
    {
127
        $ret = [];
128
        foreach ($assoc_data as $column_name => $value) {
129
            $ret[$column_name] = $this->addBinding($column_name, $value, $this->table);
130
        }
131
        return $ret;
132
    }
133
134
    public function compare($query)
135
    {
136
        if ($this->statement() !== $query->statement()) {
137
            return 'statement';
138
        }
139
140
        if (!empty(array_diff($this->bindings(), $query->bindings()))) {
141
            return 'bindings';
142
        }
143
        if (!empty(array_diff($query->bindings(), $this->bindings()))) {
144
            return 'bindings';
145
        }
146
147
        return true;
148
    }
149
}
150