Completed
Push — master ( 7eba8f...c52d76 )
by Iman
18s queued 10s
created

DbInspector::colExists()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 30
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
nc 5
nop 2
dl 0
loc 30
c 0
b 0
f 0
cc 5
rs 8.439
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 DB;
7
use Schema;
8
9
class DbInspector
10
{
11
    /**
12
     * @param $table
13
     * @return bool|null|string
14
     * @throws \Exception
15
     */
16
    public static function findPK($table)
17
    {
18
        if (! $table) {
19
            return 'id';
20
        }
21
22
        if (CRUDBooster::getCache('table_'.$table, 'primary_key')) {
23
            return CRUDBooster::getCache('table_'.$table, 'primary_key');
24
        }
25
        $table = CRUDBooster::parseSqlTable($table);
26
27
        if (! $table['table']) {
28
            throw new \Exception("parseSqlTable can't determine the table");
29
        }
30
31
        $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...
32
33
        if (! $primary_key) {
34
            return 'id';
35
        }
36
        CRUDBooster::putCache('table_'.$table, 'primary_key', $primary_key);
37
38
        return $primary_key;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $primary_key returns the type void which is incompatible with the documented return type null|string|boolean.
Loading history...
39
    }
40
41
    /**
42
     * @param $table
43
     * @param $field
44
     * @return bool
45
     */
46
    public static function isColNull($table, $field)
47
    {
48
        $cacheKey = 'field_isNull_'.$table.'_'.$field;
49
50
        if (Cache::has($cacheKey)) {
51
            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...
52
        }
53
54
        try {
55
            //MySQL & SQL Server
56
            $isNULL = DB::select(DB::raw("select IS_NULLABLE from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='$table' and COLUMN_NAME = '$field'"))[0]->IS_NULLABLE;
57
            $isNULL = ($isNULL == 'YES') ? true : false;
58
        } catch (\Exception $e) {
59
            $isNULL = false;
60
        }
61
        Cache::forever($cacheKey, $isNULL);
62
63
        return $isNULL;
64
    }
65
66
    /**
67
     * @param $columns
68
     * @return string
69
     */
70
    public static function colName($columns)
71
    {
72
        $name_col_candidate = cbConfig('NAME_FIELDS_CANDIDATE');
73
        $name_col_candidate = explode(',', $name_col_candidate);
74
        $name_col = '';
75
        foreach ($columns as $c) {
76
            foreach ($name_col_candidate as $cc) {
77
                if (strpos($c, $cc) !== false) {
78
                    $name_col = $c;
79
                    break;
80
                }
81
            }
82
            if ($name_col) {
83
                break;
84
            }
85
        }
86
        if ($name_col == '') {
87
            $name_col = 'id';
88
        }
89
90
        return $name_col;
91
    }
92
93
    /**
94
     * @param $table
95
     * @return array
96
     */
97
    public static function getTableCols($table)
98
    {
99
        $table = CRUDBooster::parseSqlTable($table);
100
        $cols = collect(DB::select('SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = :database AND TABLE_NAME = :table', [
101
            'database' => $table['database'],
102
            'table' => $table['table'],
103
        ]))->map(function ($x) {
104
            return (array) $x;
105
        })->toArray();
106
107
        return array_column($cols, 'COLUMN_NAME');
108
    }
109
110
    /**
111
     * @param $table
112
     * @param $field
113
     * @return mixed
114
     */
115
    public static function getFieldTypes($table, $field)
116
    {
117
        $field = 'field_type_'.$table.'_'.$field;
118
119
        return Cache::rememberForever($field, function () use ($table, $field) {
120
            try {
121
                //MySQL & SQL Server
122
                $typedata = DB::select(DB::raw("select DATA_TYPE from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='$table' and COLUMN_NAME = '$field'"))[0]->DATA_TYPE;
123
            } catch (\Exception $e) {
124
                $typedata = null;
125
            }
126
127
            return $typedata ?: 'varchar';
128
        });
129
    }
130
131
    /**
132
     * @param $fieldName
133
     * @return bool
134
     */
135
    public static function isForeignKeey($fieldName)
136
    {
137
        $cacheKey = 'isForeignKey_'.$fieldName;
138
139
        if (Cache::has($cacheKey)) {
140
            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...
141
        }
142
143
        $table = CRUDBooster::getTableForeignKey($fieldName);
144
        if (! $table) {
145
            return false;
146
        }
147
148
        $hasTable = Schema::hasTable($table);
149
        Cache::forever($cacheKey, $hasTable);
150
151
        return $hasTable;
152
    }
153
154
    /**
155
     * @param $table
156
     * @return null
157
     */
158
    private static function getPKforSqlServer($table)
159
    {
160
        try {
161
            $query = "
162
						SELECT Col.Column_Name,Col.Table_Name from 
163
						    INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab, 
164
						    INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col 
165
						WHERE 
166
						    Col.Constraint_Name = Tab.Constraint_Name
167
						    AND Col.Table_Name = Tab.Table_Name
168
						    AND Constraint_Type = 'PRIMARY KEY'
169
							AND Col.Table_Name = '$table[table]' 
170
					";
171
            $keys = DB::select($query);
172
            $primary_key = $keys[0]->Column_Name;
173
        } catch (\Exception $e) {
174
            $primary_key = null;
175
        }
176
177
        return $primary_key;
178
    }
179
180
    /**
181
     * @param $table
182
     * @return null
183
     */
184
    private static function findPKname($table)
185
    {
186
        if (env('DB_CONNECTION') == 'sqlsrv') {
187
            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...
188
        }
189
        try {
190
            $query = "select * from information_schema.COLUMNS where TABLE_SCHEMA = '$table[database]' and TABLE_NAME = '$table[table]' and COLUMN_KEY = 'PRI'";
191
            $keys = DB::select($query);
192
            $primary_key = $keys[0]->COLUMN_NAME;
193
        } catch (\Exception $e) {
194
            $primary_key = null;
195
        }
196
197
        return $primary_key;
198
    }
199
200
    public static function listTables()
201
    {
202
        $multiple_db = cbConfig('MULTIPLE_DATABASE_MODULE') ?: [];
203
        $db_database = cbConfig('MAIN_DB_DATABASE');
204
205
        if ($multiple_db) {
206
            try {
207
                $multiple_db[] = cbConfig('MAIN_DB_DATABASE');
208
                $query_table_schema = implode("','", $multiple_db);
209
                $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')");
210
            } catch (\Exception $e) {
211
                $tables = [];
212
            }
213
214
            return $tables;
215
        }
216
217
        try {
218
            $tables = DB::select("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.Tables WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA = '".$db_database."'");
219
        } catch (\Exception $e) {
220
            $tables = [];
221
        }
222
223
        return $tables;
224
    }
225
}