Passed
Push — main ( bf9e72...58a826 )
by Thierry
02:02
created

TableQueryAdmin   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 220
Duplicated Lines 0 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
eloc 83
dl 0
loc 220
rs 10
c 6
b 0
f 0
wmc 27

6 Methods

Rating   Name   Duplication   Size   Complexity  
A insertItem() 0 20 6
A getQueryData() 0 57 5
B getFieldInput() 0 26 7
A getQueryEntries() 0 13 4
A updateItem() 0 23 4
A deleteItem() 0 15 1
1
<?php
2
3
namespace Lagdo\DbAdmin\DbAdmin;
4
5
use Lagdo\DbAdmin\DbAdmin\Traits\QueryInputTrait;
6
use Lagdo\DbAdmin\DbAdmin\Traits\TableQueryTrait;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Lagdo\DbAdmin\DbAdmin\TableQueryTrait. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
7
use Lagdo\DbAdmin\Driver\Entity\TableFieldEntity;
8
9
use function compact;
10
use function is_array;
11
use function count;
12
use function preg_match;
13
14
/**
15
 * Admin table query functions
16
 */
17
class TableQueryAdmin extends AbstractAdmin
18
{
19
    use QueryInputTrait;
1 ignored issue
show
introduced by
The trait Lagdo\DbAdmin\DbAdmin\Traits\QueryInputTrait requires some properties which are not provided by Lagdo\DbAdmin\DbAdmin\TableQueryAdmin: $fullType, $null, $unsigned, $length, $type
Loading history...
20
    use TableQueryTrait;
1 ignored issue
show
introduced by
The trait Lagdo\DbAdmin\DbAdmin\Traits\TableQueryTrait requires some properties which are not provided by Lagdo\DbAdmin\DbAdmin\TableQueryAdmin: $privileges, $onUpdate, $default, $generated, $type, $autoIncrement
Loading history...
21
22
    /**
23
     * Get data for an input field
24
     *
25
     * @param TableFieldEntity $field
26
     * @param mixed $value
27
     * @param string|null $function
28
     * @param array $options
29
     *
30
     * @return array
31
     */
32
    protected function getFieldInput(TableFieldEntity $field, $value, $function, array $options): array
33
    {
34
        // From functions.inc.php (function input($field, $value, $function))
35
        $name = $this->util->html($this->util->bracketEscape($field->name));
36
        $save = $options["save"];
37
        $reset = ($this->driver->jush() == "mssql" && $field->autoIncrement);
38
        if (is_array($value) && !$function) {
39
            $value = json_encode($value, JSON_PRETTY_PRINT);
40
            $function = "json";
41
        }
42
        if ($reset && !$save) {
43
            $function = null;
44
        }
45
        $functions = [];
46
        if ($reset) {
47
            $functions["orig"] = $this->trans->lang('original');
48
        }
49
        $functions += $this->util->editFunctions($field);
50
        return [
51
            'type' => $this->util->html($field->fullType),
52
            'name' => $name,
53
            'field' => [
54
                'type' => $field->type,
55
            ],
56
            'functions' => $this->getEntryFunctions($field, $name, $function, $functions),
57
            'input' => $this->getEntryInput($field, $name, $value, $function, $functions, $options),
58
        ];
59
    }
60
61
    /**
62
     * @param array $fields
63
     * @param array|null $row
64
     * @param string $update
65
     * @param array $queryOptions
66
     *
67
     * @return array
68
     */
69
    private function getQueryEntries(array $fields, $row, string $update, array $queryOptions): array
70
    {
71
        $entries = [];
72
        foreach ($fields as $name => $field) {
73
            $value = $this->getRowFieldValue($field, $name, $row, $update, $queryOptions);
74
            $function = $this->getRowFieldFunction($field, $name, $value, $update, $queryOptions);
75
            if (preg_match("~time~", $field->type) && preg_match('~^CURRENT_TIMESTAMP~i', $value)) {
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type false; however, parameter $subject of preg_match() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

75
            if (preg_match("~time~", $field->type) && preg_match('~^CURRENT_TIMESTAMP~i', /** @scrutinizer ignore-type */ $value)) {
Loading history...
76
                $value = "";
77
                $function = "now";
78
            }
79
            $entries[$name] = $this->getFieldInput($field, $value, $function, $queryOptions);
80
        }
81
        return $entries;
82
    }
83
84
    /**
85
     * Get data for insert/update on a table
86
     *
87
     * @param string $table         The table name
88
     * @param array  $queryOptions  The query options
89
     *
90
     * @return array
91
     */
92
    public function getQueryData(string $table, array $queryOptions = []): array
93
    {
94
        $isInsert = (count($queryOptions) === 0); // True only on insert.
95
        // Default options
96
        $queryOptions['clone'] = false;
97
        $queryOptions['save'] = false;
98
99
        list($fields, $where, $update) = $this->getFields($table, $queryOptions);
100
        $row = $this->getQueryFirstRow($table, $where, $fields, $queryOptions);
101
102
        /* TODO: Activate this code when a driver without table support will be supported */
103
        /*if (!$this->driver->support("table") && empty($fields)) {
104
            $primary = ''; // $this->driver->primaryIdName();
105
            if (!$where) {
106
                // insert
107
                $statement = $this->driver->select($table, ["*"], [$where], ["*"]);
108
                $row = ($statement ? $statement->fetchAssoc() : false);
109
                if (!$row) {
110
                    $row = [$primary => ""];
111
                }
112
            }
113
            if ($row) {
114
                foreach ($row as $key => $val) {
115
                    if (!$where) {
116
                        $row[$key] = null;
117
                    }
118
                    $fields[$key] = [
119
                        "name" => $key,
120
                        "null" => ($key !== $primary),
121
                        "autoIncrement" => ($key === $primary)
122
                    ];
123
                }
124
            }
125
        }*/
126
127
        // From functions.inc.php (function edit_form($table, $fields, $row, $update))
128
        $entries = [];
129
        $tableName = $this->util->tableName($this->driver->tableStatusOrName($table, true));
130
        $error = null;
131
        if (($where) && $row === null) { // No row found to edit.
132
            $error = $this->trans->lang('No rows.');
133
        } elseif (empty($fields)) {
134
            $error = $this->trans->lang('You have no privileges to update this table.');
135
        } else {
136
            $entries = $this->getQueryEntries($fields, $row, $update, $queryOptions);
137
        }
138
139
        $mainActions = [
140
            'query-back' => $this->trans->lang('Back'),
141
            'query-save' => $this->trans->lang('Save'),
142
        ];
143
        if ($isInsert) {
144
            $mainActions['query-save-select'] = $this->trans->lang('Save and select');
145
        }
146
147
        $fields = $entries;
148
        return compact('mainActions', 'tableName', 'error', 'fields');
149
    }
150
151
    /**
152
     * Insert a new item in a table
153
     *
154
     * @param string $table         The table name
155
     * @param array  $queryOptions  The query options
156
     *
157
     * @return array
158
     */
159
    public function insertItem(string $table, array $queryOptions): array
160
    {
161
        list($fields, ,) = $this->getFields($table, $queryOptions);
162
163
        // From edit.inc.php
164
        $values = [];
165
        foreach ($fields as $name => $field) {
166
            $val = $this->util->processInput($field, $queryOptions);
167
            if ($val !== false && $val !== null) {
168
                $values[$this->driver->escapeId($name)] = $val;
169
            }
170
        }
171
172
        $result = $this->driver->insert($table, $values);
173
        $lastId = ($result ? $this->driver->lastAutoIncrementId() : 0);
174
        $message = $this->trans->lang('Item%s has been inserted.', ($lastId ? " $lastId" : ""));
175
176
        $error = $this->driver->error();
177
178
        return compact('result', 'message', 'error');
179
    }
180
181
    /**
182
     * Update one or more items in a table
183
     *
184
     * @param string $table         The table name
185
     * @param array  $queryOptions  The query options
186
     *
187
     * @return array
188
     */
189
    public function updateItem(string $table, array $queryOptions): array
190
    {
191
        list($fields, $where, $update) = $this->getFields($table, $queryOptions);
192
193
        // From edit.inc.php
194
        $indexes = $this->driver->indexes($table);
195
        $uniqueIds = $this->util->uniqueIds($queryOptions["where"], $indexes);
196
        $queryWhere = "\nWHERE $where";
197
198
        $values = [];
199
        foreach ($fields as $name => $field) {
200
            $val = $this->util->processInput($field, $queryOptions);
201
            if ($val !== false && $val !== null) {
202
                $values[$this->driver->escapeId($name)] = $val;
203
            }
204
        }
205
206
        $result = $this->driver->update($table, $values, $queryWhere, count($uniqueIds));
207
        $message = $this->trans->lang('Item has been updated.');
208
209
        $error = $this->driver->error();
210
211
        return compact('result', 'message', 'error');
212
    }
213
214
    /**
215
     * Delete one or more items in a table
216
     *
217
     * @param string $table         The table name
218
     * @param array  $queryOptions  The query options
219
     *
220
     * @return array
221
     */
222
    public function deleteItem(string $table, array $queryOptions): array
223
    {
224
        list($fields, $where, $update) = $this->getFields($table, $queryOptions);
225
226
        // From edit.inc.php
227
        $indexes = $this->driver->indexes($table);
228
        $uniqueIds = $this->util->uniqueIds($queryOptions["where"], $indexes);
229
        $queryWhere = "\nWHERE $where";
230
231
        $result = $this->driver->delete($table, $queryWhere, count($uniqueIds));
232
        $message = $this->trans->lang('Item has been deleted.');
233
234
        $error = $this->driver->error();
235
236
        return compact('result', 'message', 'error');
237
    }
238
}
239