Issues (2963)

Controllers/Maps/DeviceDependencyController.php (1 issue)

1
<?php
2
/**
3
 * DependencyController.php
4
 *
5
 * Controller for graphing Relationships
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 <https://www.gnu.org/licenses/>.
19
 *
20
 * @link       https://www.librenms.org
21
 *
22
 * @copyright  2019 Thomas Berberich
23
 * @author     Thomas Berberich <[email protected]>
24
 */
25
26
namespace App\Http\Controllers\Maps;
27
28
use App\Models\Device;
29
use App\Models\DeviceGroup;
30
use Illuminate\Http\Request;
31
use LibreNMS\Util\Url;
32
33
class DeviceDependencyController extends MapController
34
{
35
    protected $isolatedDeviceId = -1;
36
37
    protected $deviceIdAll = [];
38
39
    private $parentDeviceIds = [];
40
41
    protected static function deviceList($request)
42
    {
43
        $group_id = $request->get('group');
44
45
        if (! $group_id) {
46
            return Device::hasAccess($request->user())->with('parents', 'location')->get();
47
        }
48
49
        $devices = Device::inDeviceGroup($group_id)
50
            ->hasAccess($request->user())
51
            ->with([
52
                'location',
53
                'parents' => function ($query) use ($request) {
54
                    $query->hasAccess($request->user());
55
                },
56
                'children' => function ($query) use ($request) {
57
                    $query->hasAccess($request->user());
58
                }, ])
59
            ->get();
60
61
        return $devices->merge($devices->map->only('children', 'parents')->flatten())->loadMissing('parents', 'location');
62
    }
63
64
    protected function highlightDevices($devices_by_id, $device_id_list)
65
    {
66
        $new_device_list = [];
67
        foreach ($devices_by_id as $device) {
68
            if (in_array($device['id'], $device_id_list)) {
69
                $new_device_list[] = array_merge($device, $this->nodeHighlightStyle());
70
                continue;
71
            }
72
            $new_device_list[] = $device;
73
        }
74
75
        return $new_device_list;
76
    }
77
78
    protected function getParentDevices($device)
79
    {
80
        foreach ($device->parents as $parent) {
81
            if (! in_array($parent->device_id, $this->deviceIdAll)) {
82
                continue;
83
            }
84
            if (in_array($parent->device_id, $this->parentDeviceIds)) {
85
                continue;
86
            }
87
            $this->parentDeviceIds[] = $parent->device_id;
88
            if ($parent) {
89
                $this->getParentDevices($parent);
90
            }
91
        }
92
    }
93
94
    // Device Dependency Map
95
    public function dependencyMap(Request $request)
96
    {
97
        $group_id = $request->get('group');
98
        $highlight_node = $request->get('highlight_node');
99
        $show_device_path = $request->get('showparentdevicepath');
100
101
        $dependencies = [];
102
        $devices_by_id = [];
103
        $device_list = [];
104
105
        // collect Device IDs and Parents/Children to find isolated Devices
106
        $device_associations = [];
107
108
        // List all devices
109
        foreach (self::deviceList($request) as $device) {
110
            $device_list[] = ['id' => $device->device_id, 'label' => $device->hostname];
111
            $this->deviceIdAll[] = $device->device_id;
112
113
            // List all Device
114
            $devices_by_id[] = array_merge(
115
                [
116
                    'id'    => $device->device_id,
117
                    'label' => $device->shortDisplayName(),
118
                    'title' => Url::deviceLink($device, null, [], 0, 0, 0, 0),
119
                    'shape' => 'box',
120
                ],
121
                $this->deviceStyle($device, $highlight_node)
122
            );
123
124
            // List all Device Dependencies
125
            $children = $device->children;
126
            foreach ($children as $child) {
127
                $device_associations[] = $child->device_id;
128
            }
129
130
            $parents = $device->parents;
131
            foreach ($parents as $parent) {
132
                $device_associations[] = $parent->device_id;
133
                $dependencies[] = [
134
                    'from'  => $device->device_id,
135
                    'to'    => $parent->device_id,
136
                    'width' => 2,
137
                ];
138
            }
139
        }
140
141
        // highlight isolated Devices
142
        if ($highlight_node == $this->isolatedDeviceId) {
143
            $device_associations = array_unique($device_associations);
144
            $isolated_device_ids = array_diff($this->deviceIdAll, $device_associations);
145
146
            $devices_by_id = $this->highlightDevices($devices_by_id, $isolated_device_ids);
147
        } elseif ($show_device_path && ($highlight_node > 0)) {
148
            foreach (self::deviceList($request) as $device) {
149
                if ($device->device_id != $highlight_node) {
150
                    continue;
151
                }
152
                $this->getParentDevices($device);
153
                break;
154
            }
155
            $devices_by_id = $this->highlightDevices($devices_by_id, $this->parentDeviceIds);
156
        }
157
158
        $device_list_labels = array_column($device_list, 'label');
159
        array_multisort($device_list_labels, SORT_ASC, $device_list);
0 ignored issues
show
App\Http\Controllers\Maps\SORT_ASC cannot be passed to array_multisort() as the parameter $rest expects a reference. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

159
        array_multisort($device_list_labels, /** @scrutinizer ignore-type */ SORT_ASC, $device_list);
Loading history...
160
161
        $group_name = DeviceGroup::where('id', '=', $group_id)->first('name');
162
        if (! empty($group_name)) {
163
            $group_name = $group_name->name;
164
        }
165
166
        $data = [
167
            'showparentdevicepath' => $show_device_path,
168
            'isolated_device_id' => $this->isolatedDeviceId,
169
            'device_list' => $device_list,
170
            'group_id' => $group_id,
171
            'highlight_node' => $highlight_node,
172
            'node_count' => count($devices_by_id),
173
            'options' => $this->visOptions(),
174
            'nodes' => json_encode(array_values($devices_by_id)),
175
            'edges' => json_encode($dependencies),
176
            'group_name' => $group_name,
177
        ];
178
179
        return view('map.device-dependency', $data);
180
    }
181
}
182