Completed
Push — master ( 9d8405...8db55c )
by Daniel
02:33
created

MySQLiAdvancedOutput::getFieldNameForDisplay()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 10
rs 9.4285
cc 3
eloc 7
nc 3
nop 1
1
<?php
2
3
/**
4
 *
5
 * The MIT License (MIT)
6
 *
7
 * Copyright (c) 2015 Daniel Popiniuc
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a copy
10
 * of this software and associated documentation files (the "Software"), to deal
11
 * in the Software without restriction, including without limitation the rights
12
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
 * copies of the Software, and to permit persons to whom the Software is
14
 * furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included in all
17
 * copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
 * SOFTWARE.
26
 *
27
 */
28
29
namespace danielgp\common_lib;
30
31
/**
32
 * usefull functions to get quick results
33
 *
34
 * @author Daniel Popiniuc
35
 */
36
trait MySQLiAdvancedOutput
37
{
38
39
    use MySQLiByDanielGPstructures;
40
41
    protected $advCache = null;
42
43
    /**
44
     * Establish Database and Table intended to work with
45
     * (in case the DB is ommited get the default one)
46
     *
47
     * @param string $tblSrc
48
     */
49
    private function establishDatabaseAndTable($tblSrc)
50
    {
51
        if (strpos($tblSrc, '.') === false) {
52
            if (!array_key_exists('workingDatabase', $this->advCache)) {
53
                $this->advCache['workingDatabase'] = $this->getMySqlCurrentDatabase();
54
            }
55
            return [$this->advCache['workingDatabase'], $tblSrc];
56
        }
57
        return explode('.', str_replace('`', '', $tblSrc));
58
    }
59
60
    /**
61
     * Returns the name of a field for displaying
62
     *
63
     * @param array $details
64
     * @return string
65
     */
66
    protected function getFieldNameForDisplay($details)
67
    {
68
        $tableUniqueId = $details['TABLE_SCHEMA'] . '.' . $details['TABLE_NAME'];
69
        if ($details['COLUMN_COMMENT'] != '') {
70
            return $details['COLUMN_COMMENT'];
71
        } elseif (isset($this->advCache['tableStructureLocales'][$tableUniqueId][$details['COLUMN_NAME']])) {
72
            return $this->advCache['tableStructureLocales'][$tableUniqueId][$details['COLUMN_NAME']];
73
        }
74
        return $details['COLUMN_NAME'];
75
    }
76
77
    /**
78
     * Returns a Enum or Set field to use in form
79
     *
80
     * @param string $tblSrc
81
     * @param string $fldType
82
     * @param array $val
83
     * @param array $iar
84
     * @return string
85
     */
86
    private function getFieldOutputEnumSet($tblSrc, $fldType, $val, $iar = [])
87
    {
88
        $adnlThings = $this->establishDefaultEnumSet($fldType);
89
        if (array_key_exists('readonly', $val)) {
90
            return $this->getFieldOutputEnumSetReadOnly($val, $adnlThings);
91
        }
92
        $inAdtnl = $adnlThings['additional'];
93
        if ($iar !== []) {
94
            $inAdtnl = array_merge($inAdtnl, $iar);
95
        }
96
        $vlSlct    = explode(',', $this->getFieldValue($val));
97
        $slctOptns = $this->getSetOrEnum2Array($tblSrc, $val['COLUMN_NAME']);
98
        return $this->setArrayToSelect($slctOptns, $vlSlct, $val['COLUMN_NAME'] . $adnlThings['suffix'], $inAdtnl);
99
    }
100
101
    /**
102
     * Returns a Numeric field 2 use in a form
103
     *
104
     * @param string $tblSrc
105
     * @param array $value
106
     * @param array $iar
107
     * @return string
108
     */
109
    private function getFieldOutputNumeric($tblSrc, $value, $iar = [])
110
    {
111
        if ($value['EXTRA'] == 'auto_increment') {
112
            return $this->getFieldOutputNumericAI($value, $iar);
113
        }
114
        $fkArray = $this->getForeignKeysToArray($this->advCache['workingDatabase'], $tblSrc, $value['COLUMN_NAME']);
115
        if (is_null($fkArray)) {
116
            $fldNos = $this->setFieldNumbers($value);
117
            return $this->getFieldOutputTT($value, min(50, $fldNos['l']), $iar);
118
        }
119
        return $this->getFieldOutputNumericNonFK($fkArray, $value, $iar);
120
    }
121
122
    /**
123
     * Handles creation of Auto Increment numeric field type output
124
     *
125
     * @param array $value
126
     * @param array $iar
127
     * @return string
128
     */
129
    private function getFieldOutputNumericAI($value, $iar = [])
130
    {
131
        if ($this->getFieldValue($value) == '') {
132
            $spF = ['id' => $value['COLUMN_NAME'], 'style' => 'font-style:italic;'];
133
            return $this->setStringIntoTag('auto-numar', 'span', $spF);
134
        }
135
        $inAdtnl = [
136
            'type'  => 'hidden',
137
            'name'  => $value['COLUMN_NAME'],
138
            'id'    => $value['COLUMN_NAME'],
139
            'value' => $this->getFieldValue($value),
140
        ];
141
        if ($iar !== []) {
142
            $inAdtnl = array_merge($inAdtnl, $iar);
143
        }
144
        return '<b>' . $this->getFieldValue($value) . '</b>' . $this->setStringIntoShortTag('input', $inAdtnl);
145
    }
146
147
    /**
148
     * Builds field output type for numeric types if not FK
149
     *
150
     * @param array $fkArray
151
     * @param array $value
152
     * @param array $iar
153
     * @return string
154
     */
155
    private function getFieldOutputNumericNonFK($fkArray, $value, $iar = [])
156
    {
157
        $query         = $this->sQueryGenericSelectKeyValue([
158
            $fkArray[$value['COLUMN_NAME']][1],
159
            $fkArray[$value['COLUMN_NAME']][2],
160
            $fkArray[$value['COLUMN_NAME']][0],
161
        ]);
162
        $selectOptions = $this->setMySQLquery2Server($query, 'array_key_value')['result'];
163
        $selectValue   = $this->getFieldValue($value);
164
        $inAdtnl       = ['size' => 1];
165
        if ($value['IS_NULLABLE'] == 'YES') {
166
            $inAdtnl = array_merge($inAdtnl, ['include_null']);
167
        }
168
        if ($iar !== []) {
169
            $inAdtnl = array_merge($inAdtnl, $iar);
170
        }
171
        return $this->setArrayToSelect($selectOptions, $selectValue, $value['COLUMN_NAME'], $inAdtnl);
172
    }
173
174
    /**
175
     * Returns a Char field 2 use in a form
176
     *
177
     * @param string $tbl
178
     * @param string $fieldType
179
     * @param array $value
180
     * @param array $iar
181
     * @return string
182
     */
183
    private function getFieldOutputText($tbl, $fieldType, $value, $iar = [])
184
    {
185
        if (!in_array($fieldType, ['char', 'tinytext', 'varchar'])) {
186
            return '';
187
        }
188
        $foreignKeysArray = $this->getFieldOutputTextPrerequisites($tbl, $value);
189
        if (!is_null($foreignKeysArray)) {
190
            return $this->getFieldOutputTextFK($foreignKeysArray, $value, $iar);
191
        }
192
        return $this->getFieldOutputTextNonFK($value, $iar);
193
    }
194
195
    /**
196
     * Returns a Text field 2 use in a form
197
     *
198
     * @param string $fieldType
199
     * @param array $value
200
     * @param array $iar
201
     * @return string
202
     */
203
    protected function getFieldOutputTextLarge($fieldType, $value, $iar = [])
204
    {
205
        if (!in_array($fieldType, ['blob', 'text'])) {
206
            return '';
207
        }
208
        $inAdtnl = [
209
            'name' => $value['COLUMN_NAME'],
210
            'id'   => $value['COLUMN_NAME'],
211
            'rows' => 4,
212
            'cols' => 55,
213
        ];
214
        if ($iar !== []) {
215
            $inAdtnl = array_merge($inAdtnl, $iar);
216
        }
217
        return $this->setStringIntoTag($this->getFieldValue($value), 'textarea', $inAdtnl);
218
    }
219
220
    /**
221
     * Prepares the text output fields
222
     *
223
     * @param string $tbl
224
     * @param array $value
225
     * @return null|array
226
     */
227
    private function getFieldOutputTextPrerequisites($tbl, $value)
228
    {
229
        $foreignKeysArray = null;
230
        if (($tbl != 'user_rights') && ($value['COLUMN_NAME'] != 'eid')) {
231
            $database = $this->advCache['workingDatabase'];
232
            if (strpos($tbl, '`.`')) {
233
                $database = substr($tbl, 0, strpos($tbl, '`.`'));
234
            }
235
            $foreignKeysArray = $this->getForeignKeysToArray($database, $tbl, $value['COLUMN_NAME']);
236
        }
237
        return $foreignKeysArray;
238
    }
239
240
    /**
241
     * Returns a Timestamp field 2 use in a form
242
     *
243
     * @param array $dtl
244
     * @param array $iar
245
     * @return string
246
     */
247
    private function getFieldOutputTimestamp($dtl, $iar = [])
248
    {
249
        if (($dtl['COLUMN_DEFAULT'] == 'CURRENT_TIMESTAMP') || ($dtl['EXTRA'] == 'on update CURRENT_TIMESTAMP')) {
250
            return $this->getTimestamping($dtl)['input'];
251
        }
252
        $input = $this->getFieldOutputTT($dtl, 19, $iar);
253
        if (!array_key_exists('readonly', $iar)) {
254
            $input .= $this->setCalendarControlWithTime($dtl['COLUMN_NAME']);
255
        }
256
        return $input;
257
    }
258
259
    /**
260
     * Returns a Year field 2 use in a form
261
     *
262
     * @param array $details
263
     * @param array $iar
264
     * @return string
265
     */
266
    private function getFieldOutputYear($tblName, $details, $iar)
267
    {
268
        $listOfValues = [];
269
        for ($cntr = 1901; $cntr <= 2155; $cntr++) {
270
            $listOfValues[$cntr] = $cntr;
271
        }
272
        if ($iar == []) {
273
            $slDflt = $this->getFieldValue($details);
274
            return $this->setArrayToSelect($listOfValues, $slDflt, $details['COLUMN_NAME'], ['size' => 1]);
275
        }
276
        return $this->getFieldOutputText($tblName, 'varchar', $details, $iar);
277
    }
278
279
    /**
280
     * Returns an array with fields referenced by a Foreign key
281
     *
282
     * @param string $database
283
     * @param string $tblName
284
     * @param string|array $onlyCol
285
     * @return array
286
     */
287
    private function getForeignKeysToArray($database, $tblName, $onlyCol = '')
288
    {
289
        $this->setTableForeignKeyCache($database, $this->fixTableSource($tblName));
290
        $array2return = null;
291
        if (isset($this->advCache['tableFKs'][$database][$tblName])) {
292
            foreach ($this->advCache['tableFKs'][$database][$tblName] as $value) {
293
                if ($value['COLUMN_NAME'] == $onlyCol) {
294
                    $query                  = $this->getForeignKeysQuery($value);
295
                    $targetTblTxtFlds       = $this->setMySQLquery2Server($query, 'full_array_key_numbered')['result'];
296
                    $array2return[$onlyCol] = [
297
                        $this->glueDbTb($value['REFERENCED_TABLE_SCHEMA'], $value['REFERENCED_TABLE_NAME']),
298
                        $value['REFERENCED_COLUMN_NAME'],
299
                        '`' . $targetTblTxtFlds[0]['COLUMN_NAME'] . '`',
300
                    ];
301
                }
302
            }
303
        }
304
        return $array2return;
305
    }
306
307
    /**
308
     * Returns an array with possible values of a SET or ENUM column
309
     *
310
     * @param string $refTbl
311
     * @param string $refCol
312
     * @return array
313
     */
314
    protected function getSetOrEnum2Array($refTbl, $refCol)
315
    {
316
        $dat = $this->establishDatabaseAndTable($refTbl);
317
        foreach ($this->advCache['tableStructureCache'][$dat[0]][$dat[1]] as $value) {
318
            if ($value['COLUMN_NAME'] == $refCol) {
319
                $clndVls = explode(',', str_replace([$value['DATA_TYPE'], '(', "'", ')'], '', $value['COLUMN_TYPE']));
320
                $enmVls  = array_combine($clndVls, $clndVls);
321
                if ($value['IS_NULLABLE'] === 'YES') {
322
                    $enmVls['NULL'] = '';
323
                }
324
            }
325
        }
326
        ksort($enmVls);
327
        return $enmVls;
328
    }
329
330
    /**
331
     * Returns a timestamp field value
332
     *
333
     * @param array $dtl
334
     * @return array
335
     */
336
    private function getTimestamping($dtl)
337
    {
338
        $fieldValue = $this->getFieldValue($dtl);
339
        $inM        = $this->setStringIntoTag($fieldValue, 'span');
340
        if (in_array($fieldValue, ['', 'CURRENT_TIMESTAMP', 'NULL'])) {
341
            $mCN = [
342
                'InsertDateTime'        => 'data/timpul ad. informatiei',
343
                'ModificationDateTime'  => 'data/timpul modificarii inf.',
344
                'modification_datetime' => 'data/timpul modificarii inf.',
345
            ];
346
            if (array_key_exists($dtl['COLUMN_NAME'], $mCN)) {
347
                $inM = $this->setStringIntoTag($mCN[$dtl['COLUMN_NAME']], 'span', ['style' => 'font-style:italic;']);
348
            }
349
        }
350
        $lbl = '<span class="fake_label">' . $this->getFieldNameForDisplay($details) . '</span>';
0 ignored issues
show
Bug introduced by
The variable $details does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
351
        return ['label' => $lbl, 'input' => $inM];
352
    }
353
354
    protected function setNeededFieldKnown($tblName, $dtls, $features)
355
    {
356
        $iar      = $this->handleFeatures($dtls['COLUMN_NAME'], $features);
357
        $sReturn  = '';
358
        $numTypes = ['bigint', 'int', 'mediumint', 'smallint', 'tinyint', 'float', 'double', 'decimal', 'numeric'];
359
        if (in_array($dtls['DATA_TYPE'], $numTypes)) {
360
            $sReturn = $this->getFieldOutputNumeric($tblName, $dtls, $iar);
361
        } elseif (in_array($dtls['DATA_TYPE'], ['char', 'tinytext', 'varchar', 'enum', 'set', 'text', 'blob'])) {
362
            $sReturn = $this->setNeededFieldTextRelated($tblName, $dtls, $iar);
363
        } elseif (in_array($dtls['DATA_TYPE'], ['date', 'datetime', 'time', 'timestamp', 'year'])) {
364
            $sReturn = $this->setNeededFieldSingleType($tblName, $dtls, $iar);
365
        }
366
        return $this->getFieldCompletionType($dtls) . $sReturn;
367
    }
368
369
    private function setNeededFieldSingleType($tblName, $dtls, $iar)
370
    {
371
        if ($dtls['DATA_TYPE'] == 'date') {
372
            return $this->getFieldOutputDate($dtls);
373
        } elseif ($dtls['DATA_TYPE'] == 'time') {
374
            return $this->getFieldOutputTime($dtls, $iar);
375
        } elseif (in_array($dtls['DATA_TYPE'], ['datetime', 'timestamp'])) {
376
            return $this->getFieldOutputTimestamp($dtls, $iar);
377
        }
378
        return $this->getFieldOutputYear($tblName, $dtls, $iar);
379
    }
380
381
    private function setNeededFieldTextRelated($tblName, $dtls, $iar)
382
    {
383
        if (in_array($dtls['DATA_TYPE'], ['char', 'tinytext', 'varchar'])) {
384
            return $this->getFieldOutputText($tblName, $dtls['DATA_TYPE'], $dtls, $iar);
385
        } elseif (in_array($dtls['DATA_TYPE'], ['text', 'blob'])) {
386
            return $this->getFieldOutputTextLarge($dtls['DATA_TYPE'], $dtls, $iar);
387
        }
388
        return $this->getFieldOutputEnumSet($tblName, $dtls['DATA_TYPE'], $dtls, $iar);
389
    }
390
391
    /**
392
     * create a Cache for given table to use it in many places
393
     *
394
     * @param string $tblSrc
395
     */
396
    protected function setTableCache($tblSrc)
397
    {
398
        $dat = $this->establishDatabaseAndTable($tblSrc);
399
        if (!isset($this->advCache['tableStructureCache'][$dat[0]][$dat[1]])) {
400
            $this->advCache['workingDatabase']                       = $dat[0];
401
            $this->advCache['tableStructureCache'][$dat[0]][$dat[1]] = $this->getMySQLlistColumns([
402
                'TABLE_SCHEMA' => $dat[0],
403
                'TABLE_NAME'   => $dat[1],
404
            ]);
405
            $this->setTableForeignKeyCache($dat[0], $dat[1]);
406
        }
407
    }
408
409
    private function setTableForeignKeyCache($dbName, $tblName)
410
    {
411
        $frgnKs = $this->getMySQLlistIndexes([
412
            'TABLE_SCHEMA'          => $dbName,
413
            'TABLE_NAME'            => $tblName,
414
            'REFERENCED_TABLE_NAME' => 'NOT NULL',
415
        ]);
416
        if (!is_null($frgnKs)) {
417
            $this->advCache['tableFKs'][$dbName][$tblName] = $frgnKs;
418
            $this->advCache['FKcol'][$dbName][$tblName]    = array_column($frgnKs, 'COLUMN_NAME', 'CONSTRAINT_NAME');
419
        }
420
    }
421
}
422