forked from librenms/librenms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathModel.php
208 lines (179 loc) · 5.36 KB
/
Model.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
<?php
namespace LibreNMS;
abstract class Model
{
protected static $table;
protected static $primaryKey = 'id';
public static function create(array $data)
{
$instance = new static();
$instance->fill($data);
return $instance;
}
protected function fill(array $data = [])
{
foreach ($data as $field => $value) {
$this->$field = $value;
}
}
/**
* Save Models and remove invalid Models
* This the sensors array should contain all the sensors of a specific class
* It may contain sensors from multiple tables and devices, but that isn't the primary use
*
* @param int $device_id
* @param array $models
* @param array $unique_fields fields to search for an existing entry
* @param array $ignored_update_fields Don't compare these field when updating
*/
final public static function sync($device_id, array $models, $unique_fields = [], $ignored_update_fields = [])
{
// save and collect valid ids
$valid_ids = [];
foreach ($models as $model) {
/** @var $this $model */
if ($model->isValid()) {
$valid_ids[] = $model->save($unique_fields, $ignored_update_fields);
}
}
// delete invalid sensors
self::clean($device_id, $valid_ids);
}
/**
* Remove invalid Models. Passing an empty array will remove all models related to $device_id
*
* @param int $device_id
* @param array $model_ids valid Model ids
*/
protected static function clean($device_id, $model_ids)
{
$table = static::$table;
$key = static::$primaryKey;
$params = [$device_id];
$where = '`device_id`=?';
if (! empty($model_ids)) {
$where .= " AND `$key` NOT IN " . dbGenPlaceholders(count($model_ids));
$params = array_merge($params, $model_ids);
}
$rows = dbFetchRows("SELECT * FROM `$table` WHERE $where", $params);
foreach ($rows as $row) {
static::onDelete(static::create($row));
}
if (! empty($rows)) {
dbDelete($table, $where, $params);
}
}
/**
* Save this Model to the database.
*
* @param array $unique_fields fields to search for an existing entry
* @param array $ignored_update_fields Don't compare these field when updating
* @return int the id of this model in the database
*/
final public function save($unique_fields = [], $ignored_update_fields = [])
{
$db_model = $this->fetch($unique_fields);
$key = static::$primaryKey;
if ($db_model) {
$new_model = $this->toArray(array_merge([$key], $ignored_update_fields));
$update = array_diff($new_model, $db_model);
if (empty($update)) {
static::onNoUpdate();
} else {
dbUpdate($update, static::$table, "`$key`=?", [$this->$key]);
static::onUpdate($this);
}
} else {
$new_model = $this->toArray([$key]);
$this->$key = dbInsert($new_model, static::$table);
if ($this->$key !== null) {
static::onCreate($this);
}
}
return $this->$key;
}
/**
* Fetch the sensor from the database.
* If it doesn't exist, returns null.
*
* @param array $unique_fields fields to search for an existing entry
* @return array|null
*/
protected function fetch($unique_fields = [])
{
$table = static::$table;
$key = static::$primaryKey;
if (isset($this->id)) {
return dbFetchRow(
"SELECT `$table` FROM ? WHERE `$key`=?",
[$this->$key]
);
}
$where = [];
$params = [];
foreach ($unique_fields as $field) {
if (isset($this->$field)) {
$where[] = " $field=?";
$params[] = $this->$field;
}
}
if (empty($params)) {
return null;
}
$row = dbFetchRow(
"SELECT * FROM `$table` WHERE " . implode(' AND', $where),
$params
);
if (is_array($row)) {
$this->$key = $row[$key];
return $row;
}
return null;
}
/**
* Convert this Model to an array with fields that match the database
*
* @param array $exclude Exclude the listed fields
* @return array
*/
abstract public function toArray($exclude = []);
/**
* Returns if this model passes validation and should be saved to the database
*
* @return bool
*/
abstract public function isValid();
/**
* @param static $model
*/
public static function onDelete($model)
{
if (\App::runningInConsole()) {
echo '-';
}
}
/**
* @param static $model
*/
public static function onCreate($model)
{
if (\App::runningInConsole()) {
echo '+';
}
}
/**
* @param static $model
*/
public static function onUpdate($model)
{
if (\App::runningInConsole()) {
echo 'U';
}
}
public static function onNoUpdate()
{
if (\App::runningInConsole()) {
echo '.';
}
}
}