Issues (65)

src/Grammar/Query/Query.php (2 issues)

1
<?php
2
3
namespace HexMakina\Crudites\Grammar\Query;
4
5
use HexMakina\BlackBox\Database\{QueryInterface, ClauseInterface};
0 ignored issues
show
The type HexMakina\BlackBox\Database\ClauseInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
7
abstract class Query implements QueryInterface
8
{
9
    protected array $bindings = [];
10
    
11
    protected string $table;
12
    protected ?string $alias = null;
13
    
14
    
15
    protected array $clauses = [];
16
    
17
    abstract public function statement(): string;
18
    
19
    /**
20
     * Provides debugging information about the object.
21
     * This method returns an array of object properties and their values,
22
     * excluding properties that are not set.
23
     */
24
    public function __debugInfo(): array
25
    {
26
        $dbg = get_object_vars($this);
27
28
        foreach (array_keys($dbg) as $k) {
29
            if (!isset($dbg[$k])) {
30
                unset($dbg[$k]);
31
            }
32
        }
33
34
        $dbg['statement()'] = $this->statement();
35
36
        
37
        if (empty($this->bindings)) {
38
            unset($dbg['bindings']);
39
        }
40
        else{
41
            $dbg['bindings'] = json_encode($dbg['bindings']);
42
        }
43
44
        return $dbg;
45
    }
46
47
    public function __toString()
48
    {
49
        return $this->statement();
50
    }
51
52
    public function table(): string
53
    {
54
        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...
55
    }
56
57
    public function alias(): ?string
58
    {
59
        return $this->alias;
60
    }
61
62
    public function base(): string
63
    {
64
        return $this->alias ?? $this->table;
65
    }
66
67
    public function clause(string $name): ?ClauseInterface
68
    {
69
        return $this->clauses[$name] ?? null;
70
    }
71
72
    public function add(ClauseInterface $clause): self
73
    {
74
        $this->clauses[$clause->name()] = $clause;
75
        return $this;
76
    }
77
78
    public function set(ClauseInterface $clause): self
79
    {
80
        unset($this->clauses[$clause->name()]);
81
        return $this->add($clause);
82
    }
83
84
    //------------------------------------------------------------  PREP::FIELDS
85
    public function tableLabel(string $force = null)
86
    {
87
        return $force ?? $this->tableAlias();
88
    }
89
90
    public function tableAlias($setter = null): string
91
    {
92
        if ($setter !== null) {
93
            $this->alias = $setter;
94
        }
95
96
        return $this->alias ?? $this->table;
97
    }
98
99
    public function bindings(): array
100
    {
101
        if(empty($this->clauses)){
102
            return $this->bindings;
103
        }
104
105
        return array_merge($this->bindings, array_reduce($this->clauses, function ($carry, $clause) {
106
            return array_merge($carry, $clause->bindings());
107
        }, []));
108
    }
109
    
110
    public function addBinding($field, $value, $table_name = null, $bind_label = null): string
111
    {
112
        $bind_label ??= $this->bindLabel($field, $table_name);
113
114
        $this->bindings[$bind_label] = $value;
115
116
        return $bind_label;
117
    }
118
119
    public function bindLabel($field, $table_name = null): string
120
    {
121
        return ':' . $this->tableLabel($table_name) . '_' . $field;
122
    }
123
124
    public function addBindings($assoc_data, $binding_label = null): array
125
    {
126
        $ret = [];
127
        
128
        $binding_label ??= $this->base();
129
        $index = count($this->bindings);
130
        
131
        foreach ($assoc_data as $column_name => $value) {
132
            $ret[$column_name] = $this->addBinding($column_name, $value, $this->table, $binding_label.'_'.$column_name.'_'.($index++));
133
        }
134
        return $ret;
135
    }
136
137
    public function compare($query)
138
    {
139
        if ($this->statement() !== $query->statement()) {
140
            return 'statement';
141
        }
142
143
        if (!empty(array_diff($this->bindings(), $query->bindings()))) {
144
            return 'bindings';
145
        }
146
        if (!empty(array_diff($query->bindings(), $this->bindings()))) {
147
            return 'bindings';
148
        }
149
150
        return true;
151
    }
152
}
153