Completed
Push — master ( 4076e7...56163a )
by Daniel
02:39
created

MySQLiAdvancedOutput::getFieldOutputEnumSet()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 1
Metric Value
c 5
b 0
f 1
dl 0
loc 14
rs 9.4285
cc 3
eloc 10
nc 3
nop 4
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
    private 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
     * Prepares the text output fields
197
     *
198
     * @param string $tbl
199
     * @param array $value
200
     * @return null|array
201
     */
202
    private function getFieldOutputTextPrerequisites($tbl, $value)
203
    {
204
        $foreignKeysArray = null;
205
        if (($tbl != 'user_rights') && ($value['COLUMN_NAME'] != 'eid')) {
206
            $database = $this->advCache['workingDatabase'];
207
            if (strpos($tbl, '`.`')) {
208
                $database = substr($tbl, 0, strpos($tbl, '`.`'));
209
            }
210
            $foreignKeysArray = $this->getForeignKeysToArray($database, $tbl, $value['COLUMN_NAME']);
211
        }
212
        return $foreignKeysArray;
213
    }
214
215
    /**
216
     * Returns a Timestamp field 2 use in a form
217
     *
218
     * @param array $dtl
219
     * @param array $iar
220
     * @return string
221
     */
222
    private function getFieldOutputTimestamp($dtl, $iar = [])
223
    {
224
        if (($dtl['COLUMN_DEFAULT'] == 'CURRENT_TIMESTAMP') || ($dtl['EXTRA'] == 'on update CURRENT_TIMESTAMP')) {
225
            return $this->getTimestamping($dtl)['input'];
226
        }
227
        $input = $this->getFieldOutputTT($dtl, 19, $iar);
228
        if (!array_key_exists('readonly', $iar)) {
229
            $input .= $this->setCalendarControlWithTime($dtl['COLUMN_NAME']);
230
        }
231
        return $input;
232
    }
233
234
    /**
235
     * Returns a Year field 2 use in a form
236
     *
237
     * @param array $details
238
     * @param array $iar
239
     * @return string
240
     */
241
    private function getFieldOutputYear($tblName, $details, $iar)
242
    {
243
        $listOfValues = [];
244
        for ($cntr = 1901; $cntr <= 2155; $cntr++) {
245
            $listOfValues[$cntr] = $cntr;
246
        }
247
        if ($iar == []) {
248
            $slDflt = $this->getFieldValue($details);
249
            return $this->setArrayToSelect($listOfValues, $slDflt, $details['COLUMN_NAME'], ['size' => 1]);
250
        }
251
        return $this->getFieldOutputText($tblName, 'varchar', $details, $iar);
252
    }
253
254
    /**
255
     * Returns an array with fields referenced by a Foreign key
256
     *
257
     * @param string $database
258
     * @param string $tblName
259
     * @param string|array $onlyCol
260
     * @return array
261
     */
262
    private function getForeignKeysToArray($database, $tblName, $onlyCol = '')
263
    {
264
        $this->setTableForeignKeyCache($database, $this->fixTableSource($tblName));
265
        $array2return = null;
266
        if (isset($this->advCache['tableFKs'][$database][$tblName])) {
267
            foreach ($this->advCache['tableFKs'][$database][$tblName] as $value) {
268
                if ($value['COLUMN_NAME'] == $onlyCol) {
269
                    $query                  = $this->getForeignKeysQuery($value);
270
                    $targetTblTxtFlds       = $this->setMySQLquery2Server($query, 'full_array_key_numbered')['result'];
271
                    $array2return[$onlyCol] = [
272
                        $this->glueDbTb($value['REFERENCED_TABLE_SCHEMA'], $value['REFERENCED_TABLE_NAME']),
273
                        $value['REFERENCED_COLUMN_NAME'],
274
                        '`' . $targetTblTxtFlds[0]['COLUMN_NAME'] . '`',
275
                    ];
276
                }
277
            }
278
        }
279
        return $array2return;
280
    }
281
282
    /**
283
     * Build label html tag
284
     *
285
     * @param array $details
286
     * @return string
287
     */
288
    private function getLabel($details)
289
    {
290
        return '<span class="fake_label">' . $this->getFieldNameForDisplay($details) . '</span>';
291
    }
292
293
    /**
294
     * Returns an array with possible values of a SET or ENUM column
295
     *
296
     * @param string $refTbl
297
     * @param string $refCol
298
     * @return array
299
     */
300
    protected function getSetOrEnum2Array($refTbl, $refCol)
301
    {
302
        $dat = $this->establishDatabaseAndTable($refTbl);
303
        foreach ($this->advCache['tableStructureCache'][$dat[0]][$dat[1]] as $value) {
304
            if ($value['COLUMN_NAME'] == $refCol) {
305
                $clndVls = explode(',', str_replace([$value['DATA_TYPE'], '(', "'", ')'], '', $value['COLUMN_TYPE']));
306
                $enmVls  = array_combine($clndVls, $clndVls);
307
                if ($value['IS_NULLABLE'] === 'YES') {
308
                    $enmVls['NULL'] = '';
309
                }
310
            }
311
        }
312
        ksort($enmVls);
313
        return $enmVls;
314
    }
315
316
    /**
317
     * Returns a timestamp field value
318
     *
319
     * @param array $dtl
320
     * @return array
321
     */
322
    private function getTimestamping($dtl)
323
    {
324
        $fieldValue = $this->getFieldValue($dtl);
325
        $inM        = $this->setStringIntoTag($fieldValue, 'span');
326
        if (in_array($fieldValue, ['', 'CURRENT_TIMESTAMP', 'NULL'])) {
327
            $mCN = [
328
                'InsertDateTime'        => 'data/timpul ad. informatiei',
329
                'ModificationDateTime'  => 'data/timpul modificarii inf.',
330
                'modification_datetime' => 'data/timpul modificarii inf.',
331
            ];
332
            if (array_key_exists($dtl['COLUMN_NAME'], $mCN)) {
333
                $inM = $this->setStringIntoTag($mCN[$dtl['COLUMN_NAME']], 'span', ['style' => 'font-style:italic;']);
334
            }
335
        }
336
        return ['label' => $this->getLabel($dtl), 'input' => $inM];
337
    }
338
339
    /**
340
     * Builds field output w. special column name
341
     *
342
     * @param string $tableSource
343
     * @param array $dtl
344
     * @param array $features
345
     * @param string $fieldLabel
346
     * @return array
347
     */
348
    private function setField($tableSource, $dtl, $features, $fieldLabel)
349
    {
350
        if ($dtl['COLUMN_NAME'] == 'host') {
351
            $inVl = gethostbyaddr($this->tCmnRequest->server->get('REMOTE_ADDR'));
352
            return [
353
                'label' => '<label for="' . $dtl['COLUMN_NAME'] . '">Numele calculatorului</label>',
354
                'input' => '<input type="text" name="host" size="15" readonly value="' . $inVl . '" />',
355
            ];
356
        }
357
        $result = $this->setFieldInput($tableSource, $dtl, $features);
358
        return ['label' => $this->setFieldLabel($dtl, $features, $fieldLabel), 'input' => $result];
359
    }
360
361
    /**
362
     * Builds field output w. another special column name
363
     *
364
     * @param string $tableSource
365
     * @param array $dtl
366
     * @param array $features
367
     * @return string
368
     */
369
    private function setFieldInput($tableSource, $dtl, $features)
370
    {
371
        if ($dtl['COLUMN_NAME'] == 'ChoiceId') {
372
            return '<input type="text" name="ChoiceId" value="'
373
                    . $this->tCmnRequest->request->get($dtl['COLUMN_NAME']) . '" />';
374
        }
375
        return $this->setNeededFieldByType($tableSource, $dtl, $features);
376
    }
377
378
    /**
379
     * Analyse the field and returns the proper line 2 use in forms
380
     *
381
     * @param string $tableSource
382
     * @param array $details
383
     * @param array $features
384
     * @return string|array
385
     */
386
    protected function setNeededField($tableSource, $details, $features)
387
    {
388
        if (isset($features['hidden'])) {
389
            if (in_array($details['COLUMN_NAME'], $features['hidden'])) {
390
                return null;
391
            }
392
        }
393
        $fieldLabel = $this->getFieldNameForDisplay($details);
394
        if ($fieldLabel == 'hidden') {
395
            return null;
396
        }
397
        return $this->setNeededFieldFinal($tableSource, $details, $features, $fieldLabel);
398
    }
399
400
    /**
401
     * Analyse the field type and returns the proper lines 2 use in forms
402
     *
403
     * @param string $tblName
404
     * @param array $dtls
405
     * @param array $features
406
     * @return string|array
407
     */
408
    private function setNeededFieldByType($tblName, $dtls, $features)
409
    {
410
        if (isset($features['special']) && isset($features['special'][$dtls['COLUMN_NAME']])) {
411
            $sOpt = $this->setMySQLquery2Server($features['special'][$dtls['COLUMN_NAME']], 'array_key_value');
412
            return $this->setArrayToSelect($sOpt, $this->getFieldValue($dtls), $dtls['COLUMN_NAME'], ['size' => 1]);
0 ignored issues
show
Bug introduced by
It seems like $sOpt defined by $this->setMySQLquery2Ser...']], 'array_key_value') on line 411 can also be of type string; however, danielgp\common_lib\DomC...lGP::setArrayToSelect() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
413
        }
414
        return $this->setNeededFieldKnown($tblName, $dtls, $features);
415
    }
416
417
    private function setNeededFieldKnown($tblName, $dtls, $features)
418
    {
419
        $iar      = $this->handleFeatures($dtls['COLUMN_NAME'], $features);
420
        $sReturn  = '';
421
        $numTypes = ['bigint', 'int', 'mediumint', 'smallint', 'tinyint', 'float', 'double', 'decimal', 'numeric'];
422
        if (in_array($dtls['DATA_TYPE'], $numTypes)) {
423
            $sReturn = $this->getFieldOutputNumeric($tblName, $dtls, $iar);
424
        } elseif (in_array($dtls['DATA_TYPE'], ['char', 'tinytext', 'varchar', 'enum', 'set', 'text', 'blob'])) {
425
            $sReturn = $this->setNeededFieldTextRelated($tblName, $dtls, $iar);
426
        } elseif (in_array($dtls['DATA_TYPE'], ['date', 'datetime', 'time', 'timestamp', 'year'])) {
427
            $sReturn = $this->setNeededFieldSingleType($tblName, $dtls, $iar);
428
        }
429
        return $this->getFieldCompletionType($dtls) . $sReturn;
430
    }
431
432
    private function setNeededFieldFinal($tableSource, $details, $features, $fieldLabel)
433
    {
434
        $sReturn = $this->setField($tableSource, $details, $features, $fieldLabel);
435
        $lmts    = $this->setFieldNumbers($details);
436
        return '<div>' . $sReturn['label']
437
                . $this->setStringIntoTag($sReturn['input'], 'span', ['class' => 'labell'])
438
                . '<span style="font-size:x-small;font-style:italic;">&nbsp;(max. '
439
                . $lmts['M'] . (isset($lmts['d']) ? ' w. ' . $lmts['d'] . ' decimals' : '') . ')</span>'
440
                . '</div>';
441
    }
442
443
    private function setNeededFieldSingleType($tblName, $dtls, $iar)
444
    {
445
        if ($dtls['DATA_TYPE'] == 'date') {
446
            return $this->getFieldOutputDate($dtls);
447
        } elseif ($dtls['DATA_TYPE'] == 'time') {
448
            return $this->getFieldOutputTime($dtls, $iar);
449
        } elseif (in_array($dtls['DATA_TYPE'], ['datetime', 'timestamp'])) {
450
            return $this->getFieldOutputTimestamp($dtls, $iar);
451
        }
452
        return $this->getFieldOutputYear($tblName, $dtls, $iar);
453
    }
454
455
    private function setNeededFieldTextRelated($tblName, $dtls, $iar)
456
    {
457
        if (in_array($dtls['DATA_TYPE'], ['char', 'tinytext', 'varchar'])) {
458
            return $this->getFieldOutputText($tblName, $dtls['DATA_TYPE'], $dtls, $iar);
459
        } elseif (in_array($dtls['DATA_TYPE'], ['text', 'blob'])) {
460
            return $this->getFieldOutputTextLarge($dtls['DATA_TYPE'], $dtls, $iar);
461
        }
462
        return $this->getFieldOutputEnumSet($tblName, $dtls['DATA_TYPE'], $dtls, $iar);
463
    }
464
465
    /**
466
     * create a Cache for given table to use it in many places
467
     *
468
     * @param string $tblSrc
469
     */
470
    protected function setTableCache($tblSrc)
471
    {
472
        $dat = $this->establishDatabaseAndTable($tblSrc);
473
        if (!isset($this->advCache['tableStructureCache'][$dat[0]][$dat[1]])) {
474
            $this->advCache['workingDatabase']                       = $dat[0];
475
            $this->advCache['tableStructureCache'][$dat[0]][$dat[1]] = $this->getMySQLlistColumns([
476
                'TABLE_SCHEMA' => $dat[0],
477
                'TABLE_NAME'   => $dat[1],
478
            ]);
479
            $this->setTableForeignKeyCache($dat[0], $dat[1]);
480
        }
481
    }
482
483
    private function setTableForeignKeyCache($dbName, $tblName)
484
    {
485
        $frgnKs = $this->getMySQLlistIndexes([
486
            'TABLE_SCHEMA'          => $dbName,
487
            'TABLE_NAME'            => $tblName,
488
            'REFERENCED_TABLE_NAME' => 'NOT NULL',
489
        ]);
490
        if (!is_null($frgnKs)) {
491
            $this->advCache['tableFKs'][$dbName][$tblName] = $frgnKs;
492
            $this->advCache['FKcol'][$dbName][$tblName]    = array_column($frgnKs, 'COLUMN_NAME', 'CONSTRAINT_NAME');
493
        }
494
    }
495
}
496