Completed
Push — master ( 56163a...9d8405 )
by Daniel
02:39
created

MySQLiAdvancedOutput::setNeededFieldKnown()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
c 5
b 0
f 0
dl 0
loc 14
rs 9.2
cc 4
eloc 11
nc 4
nop 3
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 a Enum or Set field to use in form
62
     *
63
     * @param string $tblSrc
64
     * @param string $fldType
65
     * @param array $val
66
     * @param array $iar
67
     * @return string
68
     */
69
    private function getFieldOutputEnumSet($tblSrc, $fldType, $val, $iar = [])
70
    {
71
        $adnlThings = $this->establishDefaultEnumSet($fldType);
72
        if (array_key_exists('readonly', $val)) {
73
            return $this->getFieldOutputEnumSetReadOnly($val, $adnlThings);
74
        }
75
        $inAdtnl = $adnlThings['additional'];
76
        if ($iar !== []) {
77
            $inAdtnl = array_merge($inAdtnl, $iar);
78
        }
79
        $vlSlct    = explode(',', $this->getFieldValue($val));
80
        $slctOptns = $this->getSetOrEnum2Array($tblSrc, $val['COLUMN_NAME']);
81
        return $this->setArrayToSelect($slctOptns, $vlSlct, $val['COLUMN_NAME'] . $adnlThings['suffix'], $inAdtnl);
82
    }
83
84
    /**
85
     * Returns a Numeric field 2 use in a form
86
     *
87
     * @param string $tblSrc
88
     * @param array $value
89
     * @param array $iar
90
     * @return string
91
     */
92
    private function getFieldOutputNumeric($tblSrc, $value, $iar = [])
93
    {
94
        if ($value['EXTRA'] == 'auto_increment') {
95
            return $this->getFieldOutputNumericAI($value, $iar);
96
        }
97
        $fkArray = $this->getForeignKeysToArray($this->advCache['workingDatabase'], $tblSrc, $value['COLUMN_NAME']);
98
        if (is_null($fkArray)) {
99
            $fldNos = $this->setFieldNumbers($value);
100
            return $this->getFieldOutputTT($value, min(50, $fldNos['l']), $iar);
101
        }
102
        return $this->getFieldOutputNumericNonFK($fkArray, $value, $iar);
103
    }
104
105
    /**
106
     * Handles creation of Auto Increment numeric field type output
107
     *
108
     * @param array $value
109
     * @param array $iar
110
     * @return string
111
     */
112
    private function getFieldOutputNumericAI($value, $iar = [])
113
    {
114
        if ($this->getFieldValue($value) == '') {
115
            $spF = ['id' => $value['COLUMN_NAME'], 'style' => 'font-style:italic;'];
116
            return $this->setStringIntoTag('auto-numar', 'span', $spF);
117
        }
118
        $inAdtnl = [
119
            'type'  => 'hidden',
120
            'name'  => $value['COLUMN_NAME'],
121
            'id'    => $value['COLUMN_NAME'],
122
            'value' => $this->getFieldValue($value),
123
        ];
124
        if ($iar !== []) {
125
            $inAdtnl = array_merge($inAdtnl, $iar);
126
        }
127
        return '<b>' . $this->getFieldValue($value) . '</b>' . $this->setStringIntoShortTag('input', $inAdtnl);
128
    }
129
130
    /**
131
     * Builds field output type for numeric types if not FK
132
     *
133
     * @param array $fkArray
134
     * @param array $value
135
     * @param array $iar
136
     * @return string
137
     */
138
    private function getFieldOutputNumericNonFK($fkArray, $value, $iar = [])
139
    {
140
        $query         = $this->sQueryGenericSelectKeyValue([
141
            $fkArray[$value['COLUMN_NAME']][1],
142
            $fkArray[$value['COLUMN_NAME']][2],
143
            $fkArray[$value['COLUMN_NAME']][0],
144
        ]);
145
        $selectOptions = $this->setMySQLquery2Server($query, 'array_key_value')['result'];
146
        $selectValue   = $this->getFieldValue($value);
147
        $inAdtnl       = ['size' => 1];
148
        if ($value['IS_NULLABLE'] == 'YES') {
149
            $inAdtnl = array_merge($inAdtnl, ['include_null']);
150
        }
151
        if ($iar !== []) {
152
            $inAdtnl = array_merge($inAdtnl, $iar);
153
        }
154
        return $this->setArrayToSelect($selectOptions, $selectValue, $value['COLUMN_NAME'], $inAdtnl);
155
    }
156
157
    /**
158
     * Returns a Char field 2 use in a form
159
     *
160
     * @param string $tbl
161
     * @param string $fieldType
162
     * @param array $value
163
     * @param array $iar
164
     * @return string
165
     */
166
    private function getFieldOutputText($tbl, $fieldType, $value, $iar = [])
167
    {
168
        if (!in_array($fieldType, ['char', 'tinytext', 'varchar'])) {
169
            return '';
170
        }
171
        $foreignKeysArray = $this->getFieldOutputTextPrerequisites($tbl, $value);
172
        if (!is_null($foreignKeysArray)) {
173
            return $this->getFieldOutputTextFK($foreignKeysArray, $value, $iar);
174
        }
175
        return $this->getFieldOutputTextNonFK($value, $iar);
176
    }
177
178
    /**
179
     * Returns a Text field 2 use in a form
180
     *
181
     * @param string $fieldType
182
     * @param array $value
183
     * @param array $iar
184
     * @return string
185
     */
186
    protected function getFieldOutputTextLarge($fieldType, $value, $iar = [])
187
    {
188
        if (!in_array($fieldType, ['blob', 'text'])) {
189
            return '';
190
        }
191
        $inAdtnl = [
192
            'name' => $value['COLUMN_NAME'],
193
            'id'   => $value['COLUMN_NAME'],
194
            'rows' => 4,
195
            'cols' => 55,
196
        ];
197
        if ($iar !== []) {
198
            $inAdtnl = array_merge($inAdtnl, $iar);
199
        }
200
        return $this->setStringIntoTag($this->getFieldValue($value), 'textarea', $inAdtnl);
201
    }
202
203
    /**
204
     * Prepares the text output fields
205
     *
206
     * @param string $tbl
207
     * @param array $value
208
     * @return null|array
209
     */
210
    private function getFieldOutputTextPrerequisites($tbl, $value)
211
    {
212
        $foreignKeysArray = null;
213
        if (($tbl != 'user_rights') && ($value['COLUMN_NAME'] != 'eid')) {
214
            $database = $this->advCache['workingDatabase'];
215
            if (strpos($tbl, '`.`')) {
216
                $database = substr($tbl, 0, strpos($tbl, '`.`'));
217
            }
218
            $foreignKeysArray = $this->getForeignKeysToArray($database, $tbl, $value['COLUMN_NAME']);
219
        }
220
        return $foreignKeysArray;
221
    }
222
223
    /**
224
     * Returns a Timestamp field 2 use in a form
225
     *
226
     * @param array $dtl
227
     * @param array $iar
228
     * @return string
229
     */
230
    private function getFieldOutputTimestamp($dtl, $iar = [])
231
    {
232
        if (($dtl['COLUMN_DEFAULT'] == 'CURRENT_TIMESTAMP') || ($dtl['EXTRA'] == 'on update CURRENT_TIMESTAMP')) {
233
            return $this->getTimestamping($dtl)['input'];
234
        }
235
        $input = $this->getFieldOutputTT($dtl, 19, $iar);
236
        if (!array_key_exists('readonly', $iar)) {
237
            $input .= $this->setCalendarControlWithTime($dtl['COLUMN_NAME']);
238
        }
239
        return $input;
240
    }
241
242
    /**
243
     * Returns a Year field 2 use in a form
244
     *
245
     * @param array $details
246
     * @param array $iar
247
     * @return string
248
     */
249
    private function getFieldOutputYear($tblName, $details, $iar)
250
    {
251
        $listOfValues = [];
252
        for ($cntr = 1901; $cntr <= 2155; $cntr++) {
253
            $listOfValues[$cntr] = $cntr;
254
        }
255
        if ($iar == []) {
256
            $slDflt = $this->getFieldValue($details);
257
            return $this->setArrayToSelect($listOfValues, $slDflt, $details['COLUMN_NAME'], ['size' => 1]);
258
        }
259
        return $this->getFieldOutputText($tblName, 'varchar', $details, $iar);
260
    }
261
262
    /**
263
     * Returns an array with fields referenced by a Foreign key
264
     *
265
     * @param string $database
266
     * @param string $tblName
267
     * @param string|array $onlyCol
268
     * @return array
269
     */
270
    private function getForeignKeysToArray($database, $tblName, $onlyCol = '')
271
    {
272
        $this->setTableForeignKeyCache($database, $this->fixTableSource($tblName));
273
        $array2return = null;
274
        if (isset($this->advCache['tableFKs'][$database][$tblName])) {
275
            foreach ($this->advCache['tableFKs'][$database][$tblName] as $value) {
276
                if ($value['COLUMN_NAME'] == $onlyCol) {
277
                    $query                  = $this->getForeignKeysQuery($value);
278
                    $targetTblTxtFlds       = $this->setMySQLquery2Server($query, 'full_array_key_numbered')['result'];
279
                    $array2return[$onlyCol] = [
280
                        $this->glueDbTb($value['REFERENCED_TABLE_SCHEMA'], $value['REFERENCED_TABLE_NAME']),
281
                        $value['REFERENCED_COLUMN_NAME'],
282
                        '`' . $targetTblTxtFlds[0]['COLUMN_NAME'] . '`',
283
                    ];
284
                }
285
            }
286
        }
287
        return $array2return;
288
    }
289
290
    /**
291
     * Build label html tag
292
     *
293
     * @param array $details
294
     * @return string
295
     */
296
    private function getLabel($details)
297
    {
298
        return '<span class="fake_label">' . $this->getFieldNameForDisplay($details) . '</span>';
0 ignored issues
show
Bug introduced by
It seems like getFieldNameForDisplay() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
299
    }
300
301
    /**
302
     * Returns an array with possible values of a SET or ENUM column
303
     *
304
     * @param string $refTbl
305
     * @param string $refCol
306
     * @return array
307
     */
308
    protected function getSetOrEnum2Array($refTbl, $refCol)
309
    {
310
        $dat = $this->establishDatabaseAndTable($refTbl);
311
        foreach ($this->advCache['tableStructureCache'][$dat[0]][$dat[1]] as $value) {
312
            if ($value['COLUMN_NAME'] == $refCol) {
313
                $clndVls = explode(',', str_replace([$value['DATA_TYPE'], '(', "'", ')'], '', $value['COLUMN_TYPE']));
314
                $enmVls  = array_combine($clndVls, $clndVls);
315
                if ($value['IS_NULLABLE'] === 'YES') {
316
                    $enmVls['NULL'] = '';
317
                }
318
            }
319
        }
320
        ksort($enmVls);
321
        return $enmVls;
322
    }
323
324
    /**
325
     * Returns a timestamp field value
326
     *
327
     * @param array $dtl
328
     * @return array
329
     */
330
    private function getTimestamping($dtl)
331
    {
332
        $fieldValue = $this->getFieldValue($dtl);
333
        $inM        = $this->setStringIntoTag($fieldValue, 'span');
334
        if (in_array($fieldValue, ['', 'CURRENT_TIMESTAMP', 'NULL'])) {
335
            $mCN = [
336
                'InsertDateTime'        => 'data/timpul ad. informatiei',
337
                'ModificationDateTime'  => 'data/timpul modificarii inf.',
338
                'modification_datetime' => 'data/timpul modificarii inf.',
339
            ];
340
            if (array_key_exists($dtl['COLUMN_NAME'], $mCN)) {
341
                $inM = $this->setStringIntoTag($mCN[$dtl['COLUMN_NAME']], 'span', ['style' => 'font-style:italic;']);
342
            }
343
        }
344
        return ['label' => $this->getLabel($dtl), 'input' => $inM];
345
    }
346
347
    protected function setNeededFieldKnown($tblName, $dtls, $features)
348
    {
349
        $iar      = $this->handleFeatures($dtls['COLUMN_NAME'], $features);
350
        $sReturn  = '';
351
        $numTypes = ['bigint', 'int', 'mediumint', 'smallint', 'tinyint', 'float', 'double', 'decimal', 'numeric'];
352
        if (in_array($dtls['DATA_TYPE'], $numTypes)) {
353
            $sReturn = $this->getFieldOutputNumeric($tblName, $dtls, $iar);
354
        } elseif (in_array($dtls['DATA_TYPE'], ['char', 'tinytext', 'varchar', 'enum', 'set', 'text', 'blob'])) {
355
            $sReturn = $this->setNeededFieldTextRelated($tblName, $dtls, $iar);
356
        } elseif (in_array($dtls['DATA_TYPE'], ['date', 'datetime', 'time', 'timestamp', 'year'])) {
357
            $sReturn = $this->setNeededFieldSingleType($tblName, $dtls, $iar);
358
        }
359
        return $this->getFieldCompletionType($dtls) . $sReturn;
360
    }
361
362
    private function setNeededFieldSingleType($tblName, $dtls, $iar)
363
    {
364
        if ($dtls['DATA_TYPE'] == 'date') {
365
            return $this->getFieldOutputDate($dtls);
366
        } elseif ($dtls['DATA_TYPE'] == 'time') {
367
            return $this->getFieldOutputTime($dtls, $iar);
368
        } elseif (in_array($dtls['DATA_TYPE'], ['datetime', 'timestamp'])) {
369
            return $this->getFieldOutputTimestamp($dtls, $iar);
370
        }
371
        return $this->getFieldOutputYear($tblName, $dtls, $iar);
372
    }
373
374
    private function setNeededFieldTextRelated($tblName, $dtls, $iar)
375
    {
376
        if (in_array($dtls['DATA_TYPE'], ['char', 'tinytext', 'varchar'])) {
377
            return $this->getFieldOutputText($tblName, $dtls['DATA_TYPE'], $dtls, $iar);
378
        } elseif (in_array($dtls['DATA_TYPE'], ['text', 'blob'])) {
379
            return $this->getFieldOutputTextLarge($dtls['DATA_TYPE'], $dtls, $iar);
380
        }
381
        return $this->getFieldOutputEnumSet($tblName, $dtls['DATA_TYPE'], $dtls, $iar);
382
    }
383
384
    /**
385
     * create a Cache for given table to use it in many places
386
     *
387
     * @param string $tblSrc
388
     */
389
    protected function setTableCache($tblSrc)
390
    {
391
        $dat = $this->establishDatabaseAndTable($tblSrc);
392
        if (!isset($this->advCache['tableStructureCache'][$dat[0]][$dat[1]])) {
393
            $this->advCache['workingDatabase']                       = $dat[0];
394
            $this->advCache['tableStructureCache'][$dat[0]][$dat[1]] = $this->getMySQLlistColumns([
395
                'TABLE_SCHEMA' => $dat[0],
396
                'TABLE_NAME'   => $dat[1],
397
            ]);
398
            $this->setTableForeignKeyCache($dat[0], $dat[1]);
399
        }
400
    }
401
402
    private function setTableForeignKeyCache($dbName, $tblName)
403
    {
404
        $frgnKs = $this->getMySQLlistIndexes([
405
            'TABLE_SCHEMA'          => $dbName,
406
            'TABLE_NAME'            => $tblName,
407
            'REFERENCED_TABLE_NAME' => 'NOT NULL',
408
        ]);
409
        if (!is_null($frgnKs)) {
410
            $this->advCache['tableFKs'][$dbName][$tblName] = $frgnKs;
411
            $this->advCache['FKcol'][$dbName][$tblName]    = array_column($frgnKs, 'COLUMN_NAME', 'CONSTRAINT_NAME');
412
        }
413
    }
414
}
415