Passed
Pull Request — master (#1140)
by Iman
03:41
created

DbInspector::getTableCols()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
nc 1
nop 1
dl 0
loc 11
c 0
b 0
f 0
cc 1
rs 9.4285
1
<?php
2
3
namespace crocodicstudio\crudbooster\helpers;
4
5
use Cache;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, crocodicstudio\crudbooster\helpers\Cache. 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...
6
use crocodicstudio\crudbooster\helpers\Cache as CbCache;
7
use DB;
8
use Illuminate\Support\Facades\Schema;
9
10
class DbInspector
11
{
12
    /**
13
     * @param $table
14
     * @return bool|null|string
15
     * @throws \Exception
16
     */
17
    public static function findPK($table)
18
    {
19
        if (! $table) {
20
            return 'id';
21
        }
22
23
        if (CbCache::get('table_'.$table, 'primaryKey')) {
24
            return CbCache::get('table_'.$table, 'primaryKey');
25
        }
26
        $table = CRUDBooster::parseSqlTable($table);
27
28
        if (! $table['table']) {
29
            throw new \Exception("parseSqlTable can't determine the table");
30
        }
31
32
        $primaryKey = self::findPKname($table);
33
34
        if (! $primaryKey) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $primaryKey of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
35
            return 'id';
36
        }
37
        CbCache::put('table_'.$table, 'primaryKey', $primaryKey);
38
39
        return $primaryKey;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $primaryKey returns the type array which is incompatible with the documented return type null|string|boolean.
Loading history...
40
    }
41
42
    /**
43
     * @param $table
44
     * @param $field
45
     * @return bool
46
     */
47
    public static function isColNull($table, $field)
48
    {
49
        $cacheKey = 'field_isNull_'.$table.'_'.$field;
50
51
        if (Cache::has($cacheKey)) {
52
            return Cache::get($cacheKey);
53
        }
54
55
        try {
56
            //MySQL & SQL Server
57
            $isNULL = DB::select(DB::raw("select IS_NULLABLE from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='$table' and COLUMN_NAME = '$field'"))[0]->IS_NULLABLE;
58
            $isNULL = ($isNULL == 'YES') ? true : false;
59
        } catch (\Exception $e) {
60
            $isNULL = false;
61
        }
62
        Cache::forever($cacheKey, $isNULL);
63
64
        return $isNULL;
65
    }
66
67
    /**
68
     * @param $columns
69
     * @return string
70
     */
71
    public static function colName($columns)
72
    {
73
        $nameColCandidate = explode(',', cbConfig('NAME_FIELDS_CANDIDATE'));
74
75
        foreach ($columns as $c) {
76
            foreach ($nameColCandidate as $cc) {
77
                if (strpos($c, $cc) !== false) {
78
                    return $c;
79
                }
80
            }
81
        }
82
83
        return 'id';
84
    }
85
86
    /**
87
     * @param $fieldName
88
     * @return bool
89
     */
90
    public static function isForeignKey($fieldName)
91
    {
92
        $cacheKey = 'isForeignKey_'.$fieldName;
93
94
        if (Cache::has($cacheKey)) {
95
            return Cache::get($cacheKey);
96
        }
97
98
        $table = self::getTableForeignKey($fieldName);
99
        if (! $table) {
100
            return false;
101
        }
102
103
        $hasTable = Schema::hasTable($table);
104
        Cache::forever($cacheKey, $hasTable);
105
106
        return $hasTable;
107
    }
108
109
    /**
110
     * @param $table
111
     * @return null
112
     */
113
    private static function getPKforSqlServer($table)
114
    {
115
        try {
116
            $query = "
117
						SELECT Col.Column_Name,Col.Table_Name from 
118
						    INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab, 
119
						    INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col 
120
						WHERE 
121
						    Col.Constraint_Name = Tab.Constraint_Name
122
						    AND Col.Table_Name = Tab.Table_Name
123
						    AND Constraint_Type = 'PRIMARY KEY'
124
							AND Col.Table_Name = '$table[table]' 
125
					";
126
            $keys = DB::select($query);
127
            $primaryKey = $keys[0]->Column_Name;
128
        } catch (\Exception $e) {
129
            $primaryKey = null;
130
        }
131
132
        return $primaryKey;
133
    }
134
135
    /**
136
     * @param $table
137
     * @return array
138
     */
139
    private static function findPKname($table)
140
    {
141
        if (env('DB_CONNECTION') == 'sqlsrv') {
142
            return self::getPKforSqlServer($table);
0 ignored issues
show
Bug introduced by
Are you sure the usage of self::getPKforSqlServer($table) targeting crocodicstudio\crudboost...or::getPKforSqlServer() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
143
        }
144
        try {
145
            $query = "select * from information_schema.COLUMNS where TABLE_SCHEMA = '$table[database]' and TABLE_NAME = '$table[table]' and COLUMN_KEY = 'PRI'";
146
            $keys = DB::select($query);
147
            $primaryKey = $keys[0]->COLUMN_NAME;
148
        } catch (\Exception $e) {
149
            $primaryKey = null;
150
        }
151
152
        return $primaryKey;
153
    }
154
155
    public static function listTables()
156
    {
157
        $multiple_db = cbConfig('MULTIPLE_DATABASE_MODULE') ?: [];
158
        $db_database = cbConfig('MAIN_DB_DATABASE');
159
160
        if ($multiple_db) {
161
            try {
162
                $multiple_db[] = cbConfig('MAIN_DB_DATABASE');
163
                $query_table_schema = implode("','", $multiple_db);
164
                $tables = DB::select("SELECT CONCAT(TABLE_SCHEMA,'.',TABLE_NAME) FROM INFORMATION_SCHEMA.Tables WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA != 'mysql' AND TABLE_SCHEMA != 'performance_schema' AND TABLE_SCHEMA != 'information_schema' AND TABLE_SCHEMA != 'phpmyadmin' AND TABLE_SCHEMA IN ('$query_table_schema')");
165
            } catch (\Exception $e) {
166
                $tables = [];
167
            }
168
169
            return $tables;
170
        }
171
172
        try {
173
            $tables = DB::select("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.Tables WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA = '".$db_database."'");
174
        } catch (\Exception $e) {
175
            $tables = [];
176
        }
177
178
        return $tables;
179
    }
180
181
    public static function getForeignKey($parent_table, $child_table)
182
    {
183
        $parent_table = CRUDBooster::parseSqlTable($parent_table)['table'];
184
        $child_table = CRUDBooster::parseSqlTable($child_table)['table'];
185
186
        if (\Schema::hasColumn($child_table, 'id_'.$parent_table)) {
187
            return 'id_'.$parent_table;
188
        }
189
        return $parent_table.'_id';
190
    }
191
192
    public static function getTableForeignKey($fieldName)
193
    {
194
        if (self::isForeignKey($fieldName)) {
195
            return str_replace(['_id', 'id_'], '', $fieldName);
196
        }
197
    }
198
}