Completed
Push — master ( d6a5af...93636f )
by Iman
16s
created

DbInspector::isForeignKey()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 9
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 17
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 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, 'primary_key')) {
24
            return CbCache::get('table_'.$table, 'primary_key');
25
        }
26
        $table = CRUDBooster::parseSqlTable($table);
27
28
        if (! $table['table']) {
29
            throw new \Exception("parseSqlTable can't determine the table");
30
        }
31
32
        $primary_key = self::findPKname($table);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $primary_key is correct as self::findPKname($table) targeting crocodicstudio\crudboost...Inspector::findPKname() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

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

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

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

Loading history...
33
34
        if (! $primary_key) {
0 ignored issues
show
introduced by
$primary_key is of type null, thus it always evaluated to false.
Loading history...
35
            return 'id';
36
        }
37
        CbCache::put('table_'.$table, 'primary_key', $primary_key);
38
39
        return $primary_key;
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);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Cache::get($cacheKey) returns the type Illuminate\Contracts\Cache\Repository which is incompatible with the documented return type boolean.
Loading history...
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
        $name_col_candidate = cbConfig('NAME_FIELDS_CANDIDATE');
74
        $name_col_candidate = explode(',', $name_col_candidate);
75
        $name_col = '';
76
        foreach ($columns as $c) {
77
            foreach ($name_col_candidate as $cc) {
78
                if (strpos($c, $cc) !== false) {
79
                    $name_col = $c;
80
                    break;
81
                }
82
            }
83
            if ($name_col) {
84
                break;
85
            }
86
        }
87
        if ($name_col == '') {
88
            $name_col = 'id';
89
        }
90
91
        return $name_col;
92
    }
93
94
    /**
95
     * @param $table
96
     * @return array
97
     */
98
    public static function getTableCols($table)
99
    {
100
        $table = CRUDBooster::parseSqlTable($table);
101
        $cols = collect(DB::select('SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = :database AND TABLE_NAME = :table', [
102
            'database' => $table['database'],
103
            'table' => $table['table'],
104
        ]))->map(function ($x) {
105
            return (array) $x;
106
        })->toArray();
107
108
        return array_column($cols, 'COLUMN_NAME');
109
    }
110
111
    /**
112
     * @param $table
113
     * @param $field
114
     * @return mixed
115
     */
116
    public static function getFieldTypes($table, $field)
117
    {
118
        $field = 'field_type_'.$table.'_'.$field;
119
120
        return Cache::rememberForever($field, function () use ($table, $field) {
121
            try {
122
                //MySQL & SQL Server
123
                $typedata = DB::select(DB::raw("select DATA_TYPE from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='$table' and COLUMN_NAME = '$field'"))[0]->DATA_TYPE;
124
            } catch (\Exception $e) {
125
                $typedata = null;
126
            }
127
128
            return $typedata ?: 'varchar';
129
        });
130
    }
131
132
    /**
133
     * @param $fieldName
134
     * @return bool
135
     */
136
    public static function isForeignKey($fieldName)
137
    {
138
        $cacheKey = 'isForeignKey_'.$fieldName;
139
140
        if (Cache::has($cacheKey)) {
141
            return Cache::get($cacheKey);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Cache::get($cacheKey) returns the type Illuminate\Contracts\Cache\Repository which is incompatible with the documented return type boolean.
Loading history...
142
        }
143
144
        $table = CRUDBooster::getTableForeignKey($fieldName);
145
        if (! $table) {
146
            return false;
147
        }
148
149
        $hasTable = Schema::hasTable($table);
150
        Cache::forever($cacheKey, $hasTable);
151
152
        return $hasTable;
153
    }
154
155
    /**
156
     * @param $table
157
     * @return null
158
     */
159
    private static function getPKforSqlServer($table)
160
    {
161
        try {
162
            $query = "
163
						SELECT Col.Column_Name,Col.Table_Name from 
164
						    INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab, 
165
						    INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col 
166
						WHERE 
167
						    Col.Constraint_Name = Tab.Constraint_Name
168
						    AND Col.Table_Name = Tab.Table_Name
169
						    AND Constraint_Type = 'PRIMARY KEY'
170
							AND Col.Table_Name = '$table[table]' 
171
					";
172
            $keys = DB::select($query);
173
            $primary_key = $keys[0]->Column_Name;
174
        } catch (\Exception $e) {
175
            $primary_key = null;
176
        }
177
178
        return $primary_key;
179
    }
180
181
    /**
182
     * @param $table
183
     * @return null
184
     */
185
    private static function findPKname($table)
186
    {
187
        if (env('DB_CONNECTION') == 'sqlsrv') {
188
            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...
189
        }
190
        try {
191
            $query = "select * from information_schema.COLUMNS where TABLE_SCHEMA = '$table[database]' and TABLE_NAME = '$table[table]' and COLUMN_KEY = 'PRI'";
192
            $keys = DB::select($query);
193
            $primary_key = $keys[0]->COLUMN_NAME;
194
        } catch (\Exception $e) {
195
            $primary_key = null;
196
        }
197
198
        return $primary_key;
199
    }
200
201
    public static function listTables()
202
    {
203
        $multiple_db = cbConfig('MULTIPLE_DATABASE_MODULE') ?: [];
204
        $db_database = cbConfig('MAIN_DB_DATABASE');
205
206
        if ($multiple_db) {
207
            try {
208
                $multiple_db[] = cbConfig('MAIN_DB_DATABASE');
209
                $query_table_schema = implode("','", $multiple_db);
210
                $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')");
211
            } catch (\Exception $e) {
212
                $tables = [];
213
            }
214
215
            return $tables;
216
        }
217
218
        try {
219
            $tables = DB::select("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.Tables WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA = '".$db_database."'");
220
        } catch (\Exception $e) {
221
            $tables = [];
222
        }
223
224
        return $tables;
225
    }
226
227
    public static function getForeignKey($parent_table, $child_table)
228
    {
229
        $parent_table = CRUDBooster::parseSqlTable($parent_table)['table'];
230
        $child_table = CRUDBooster::parseSqlTable($child_table)['table'];
231
232
        if (\Schema::hasColumn($child_table, 'id_'.$parent_table)) {
233
            return 'id_'.$parent_table;
234
        }
235
        return $parent_table.'_id';
236
    }
237
}