Issues (28)

src/Db/Facades/QueryFacade.php (2 issues)

Severity
1
<?php
2
3
namespace Lagdo\DbAdmin\Db\Facades;
4
5
use Lagdo\DbAdmin\Driver\Entity\TableFieldEntity;
6
7
use function compact;
8
use function is_string;
9
use function is_array;
10
use function count;
11
use function preg_match;
12
13
/**
14
 * Facade to table query functions
15
 */
16
class QueryFacade extends AbstractFacade
17
{
18
    use Traits\QueryInputTrait;
0 ignored issues
show
The trait Lagdo\DbAdmin\Db\Facades\Traits\QueryInputTrait requires some properties which are not provided by Lagdo\DbAdmin\Db\Facades\QueryFacade: $fullType, $trans, $null, $str, $unsigned, $length, $type
Loading history...
19
    use Traits\QueryTrait;
0 ignored issues
show
The trait Lagdo\DbAdmin\Db\Facades\Traits\QueryTrait requires some properties which are not provided by Lagdo\DbAdmin\Db\Facades\QueryFacade: $privileges, $onUpdate, $default, $generated, $type, $autoIncrement
Loading history...
20
21
    /**
22
     * Get data for an input field
23
     *
24
     * @param TableFieldEntity $field
25
     * @param mixed $value
26
     * @param string|null $function
27
     * @param array $options
28
     *
29
     * @return array
30
     */
31
    protected function getFieldInput(TableFieldEntity $field, $value, $function, array $options): array
32
    {
33
        // From functions.inc.php (function input($field, $value, $function))
34
        $name = $this->utils->str->html($this->driver->bracketEscape($field->name));
35
        $save = $options['save'];
36
        $reset = ($this->driver->jush() == 'mssql' && $field->autoIncrement);
37
        if (is_array($value) && !$function) {
38
            $value = json_encode($value, JSON_PRETTY_PRINT);
39
            $function = 'json';
40
        }
41
        if ($reset && !$save) {
42
            $function = null;
43
        }
44
        $functions = [];
45
        if ($reset) {
46
            $functions['orig'] = $this->utils->trans->lang('original');
47
        }
48
        $functions += $this->admin->editFunctions($field);
49
        return [
50
            'type' => $this->utils->str->html($field->fullType),
51
            'name' => $name,
52
            'field' => [
53
                'type' => $field->type,
54
            ],
55
            'functions' => $this->getEntryFunctions($field, $name, $function, $functions),
56
            'input' => $this->getEntryInput($field, $name, $value, $function, $functions, $options),
57
        ];
58
    }
59
60
    /**
61
     * @param array $fields
62
     * @param array|null $row
63
     * @param string $update
64
     * @param array $queryOptions
65
     *
66
     * @return array
67
     */
68
    private function getQueryEntries(array $fields, $row, string $update, array $queryOptions): array
69
    {
70
        $entries = [];
71
        foreach ($fields as $name => $field) {
72
            $value = $this->getRowFieldValue($field, $name, $row, $update, $queryOptions);
73
            $function = $this->getRowFieldFunction($field, $name, $value, $update, $queryOptions);
74
            if (preg_match('~time~', $field->type) && is_string($value) &&
75
                preg_match('~^CURRENT_TIMESTAMP~i', $value)) {
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
        // Default options
95
        $queryOptions['clone'] = false;
96
        $queryOptions['save'] = false;
97
98
        [$fields, $where, $update] = $this->getFields($table, $queryOptions);
99
        $row = $this->getQueryFirstRow($table, $where, $fields, $queryOptions);
100
101
        /* TODO: Activate this code when a driver without table support will be supported */
102
        /*if (!$this->driver->support('table') && empty($fields)) {
103
            $primary = ''; // $this->driver->primaryIdName();
104
            if (!$where) {
105
                // insert
106
                $statement = $this->driver->select($table, ['*'], [$where], ['*']);
107
                $row = ($statement ? $statement->fetchAssoc() : false);
108
                if (!$row) {
109
                    $row = [$primary => ''];
110
                }
111
            }
112
            if ($row) {
113
                foreach ($row as $key => $val) {
114
                    if (!$where) {
115
                        $row[$key] = null;
116
                    }
117
                    $fields[$key] = [
118
                        'name' => $key,
119
                        'null' => ($key !== $primary),
120
                        'autoIncrement' => ($key === $primary)
121
                    ];
122
                }
123
            }
124
        }*/
125
126
        // From functions.inc.php (function edit_form($table, $fields, $row, $update))
127
        $entries = [];
128
        $tableName = $this->admin->tableName($this->driver->tableStatusOrName($table, true));
129
        $error = null;
130
        if (($where) && $row === null) { // No row found to edit.
131
            $error = $this->utils->trans->lang('No rows.');
132
        } elseif (empty($fields)) {
133
            $error = $this->utils->trans->lang('You have no privileges to update this table.');
134
        } else {
135
            $entries = $this->getQueryEntries($fields, $row, $update, $queryOptions);
136
        }
137
138
        $fields = $entries;
139
        return compact('tableName', 'error', 'fields');
140
    }
141
142
    /**
143
     * Insert a new item in a table
144
     *
145
     * @param string $table         The table name
146
     * @param array  $queryOptions  The query options
147
     *
148
     * @return array
149
     */
150
    public function insertItem(string $table, array $queryOptions): array
151
    {
152
        list($fields, ,) = $this->getFields($table, $queryOptions);
153
154
        // From edit.inc.php
155
        $values = [];
156
        foreach ($fields as $name => $field) {
157
            $val = $this->admin->processInput($field, $queryOptions);
158
            if ($val !== false && $val !== null) {
159
                $values[$this->driver->escapeId($name)] = $val;
160
            }
161
        }
162
163
        $result = $this->driver->insert($table, $values);
164
        $lastId = ($result ? $this->driver->lastAutoIncrementId() : 0);
165
        $message = $this->utils->trans->lang('Item%s has been inserted.', ($lastId ? " $lastId" : ''));
166
167
        $error = $this->driver->error();
168
169
        return compact('result', 'message', 'error');
170
    }
171
172
    /**
173
     * Update one or more items in a table
174
     *
175
     * @param string $table         The table name
176
     * @param array  $queryOptions  The query options
177
     *
178
     * @return array
179
     */
180
    public function updateItem(string $table, array $queryOptions): array
181
    {
182
        list($fields, $where, ) = $this->getFields($table, $queryOptions);
183
184
        // From edit.inc.php
185
        $indexes = $this->driver->indexes($table);
186
        $uniqueIds = $this->admin->uniqueIds($queryOptions['where'], $indexes);
187
        $queryWhere = "\nWHERE $where";
188
189
        $values = [];
190
        foreach ($fields as $name => $field) {
191
            $val = $this->admin->processInput($field, $queryOptions);
192
            if ($val !== false && $val !== null) {
193
                $values[$this->driver->escapeId($name)] = $val;
194
            }
195
        }
196
197
        $result = $this->driver->update($table, $values, $queryWhere, count($uniqueIds));
198
        $message = $this->utils->trans->lang('Item has been updated.');
199
200
        $error = $this->driver->error();
201
202
        return compact('result', 'message', 'error');
203
    }
204
205
    /**
206
     * Delete one or more items in a table
207
     *
208
     * @param string $table         The table name
209
     * @param array  $queryOptions  The query options
210
     *
211
     * @return array
212
     */
213
    public function deleteItem(string $table, array $queryOptions): array
214
    {
215
        list($fields, $where, $update) = $this->getFields($table, $queryOptions);
216
217
        // From edit.inc.php
218
        $indexes = $this->driver->indexes($table);
219
        $uniqueIds = $this->admin->uniqueIds($queryOptions['where'], $indexes);
220
        $queryWhere = "\nWHERE $where";
221
222
        $result = $this->driver->delete($table, $queryWhere, count($uniqueIds));
223
        $message = $this->utils->trans->lang('Item has been deleted.');
224
225
        $error = $this->driver->error();
226
227
        return compact('result', 'message', 'error');
228
    }
229
}
230