Completed
Pull Request — develop (#143)
by Tony
06:09
created

QueryBuilderFilter::generateMacroFilter()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 13
rs 9.4285
cc 2
eloc 9
nc 2
nop 2
1
<?php
2
/**
3
 * QueryBuilderFilter.php
4
 *
5
 * -Description-
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 * @package    LibreNMS
21
 * @link       http://librenms.org
22
 * @copyright  2016 Tony Murray
23
 * @author     Tony Murray <[email protected]>
24
 */
25
26
namespace app;
27
28
29
use Cache;
30
use DB;
31
use Log;
32
use Settings;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, app\Settings.

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...
33
34
class QueryBuilderFilter
35
{
36
    public static function getAlertFilter()
37
    {
38
        return json_encode(self::generateMacroFilter('alert.macros.rule', self::generateTableFilter()));
39
    }
40
41
    private static function generateMacroFilter($setting, $filter = [])
42
    {
43
        foreach (Settings::get($setting, []) as $key => $value) {
44
            $filter[] = [
45
                'id'        => 'macros.'.$key,
46
                'type'      => 'integer',
47
                'input'     => 'radio',
48
                'values'    => ['1' => 'Yes', '0' => 'No'],
49
                'operators' => ['equal'],
50
            ];
51
        }
52
        return $filter;
53
    }
54
55
    private static function generateTableFilter($filter = [])
56
    {
57
        $check_start = microtime(true);
58
        $cached = Cache::get('query_builder_table_filter_migrations', []);
59
        $db = DB::table('migrations')->pluck('migration');
60
61
        if ($db != $cached) {
62
            Cache::forget('query_builder_table_filter');
63
            Cache::add('query_builder_table_filter_migrations', $db, 30);
64
        }
65
        $check_end = microtime(true);
66
        Log::info('Query Builder filter check time: '.($check_end - $check_start).'s');
67
68
69
        return Cache::remember('query_builder_table_filter', 300, function() use ($filter) {
70
            $schema = DB::getDoctrineSchemaManager();
71
72
            // Doctrine DBAL has issues with enums, pretend they are strings
73
            $schema->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
74
75
//            $validTypes = ['string', 'integer', 'double', 'date', 'time', 'datetime', 'boolean'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
76
            $ignoreTypes = ['blob', 'binary'];
77
78
            $tables = $schema->listTables();
79
            foreach ($tables as $table) {
80
                $columns = $schema->listTableColumns($table->getName());
81
                $tableName = $table->getName();
82
83
                // only allow tables with direct association to device_id for now
84
                if (!$table->hasColumn('device_id')) {
85
                    continue;
86
                }
87
88
                foreach ($columns as $column) {
89
                    $item = [];
90
                    $type = $column->getType()->getName();
91
                    $name = $column->getName();
92
93
                    switch ($type) {
94
                        case 'text':
95
//                            $item['input'] = 'textarea';
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
96
                        case 'string':
97
                            $item['type'] = 'string';
98
                            break;
99
100
                        case 'integer':
101
                        case 'smallint':
102
                        case 'bigint':
103
                            $item['type'] = 'integer';
104
                            break;
105
106
                        case 'double':
107
                        case 'float':
108
                        case 'decimal':
109
                            $item['type'] = 'double';
110
                            break;
111
112
                        case 'date':
113
                            $item['type'] = 'date';
114
                            break;
115
116
                        case 'time':
117
                            $item['type'] = 'time';
118
                            break;
119
120
                        case 'datetime':
121
                            $item['type'] = 'datetime';
122
                            break;
123
124
                        case 'boolean':
125
                            $item['type'] = 'boolean';
126
                            break;
127
128
                    }
129
130
                    if (!isset($item['type'])) {
131
                        if (!in_array($type, $ignoreTypes)) {
132
                            dd($type);
133
                        }
134
                        continue;
135
                    }
136
137
                    // ignore device id columns, except in the devices table
138
                    if ($name == 'device_id') {
139
                        if ($tableName != 'devices') {
140
                            continue;
141
                        }
142
                    }
143
144
                    $item['id'] = $tableName.'.'.$name;
145
                    $filter[] = $item;
146
                }
147
            }
148
            return $filter;
149
        });
150
    }
151
152
    public static function getGroupFilter()
153
    {
154
        return json_encode(self::generateMacroFilter('alert.macros.group', self::generateTableFilter()));
155
    }
156
}