Skip to content

Commit a328686

Browse files
stonebuzztrasher
authored andcommitted
migrate dynamic group search from serialized to JSON format
1 parent 6b8b0be commit a328686

4 files changed

Lines changed: 336 additions & 7 deletions

File tree

front/computergroup.form.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,13 @@
118118
// save search parameters for dynamic group
119119
if (isset($_GET['save'])) {
120120
$input = ['plugin_databaseinventory_computergroups_id' => $_GET['plugin_databaseinventory_computergroups_id']];
121-
$search = serialize([
121+
$search = json_encode([
122+
'is_deleted' => $_GET['is_deleted'] ?? 0,
122123
'is_deleted' => isset($_GET['is_deleted']) ? $_GET['is_deleted'] : 0 ,
123124
'as_map' => isset($_GET['as_map']) ? $_GET['as_map'] : 0,
124125
'criteria' => $_GET['criteria'],
125126
'metacriteria' => isset($_GET['metacriteria']) ? $_GET['metacriteria'] : [],
126-
]);
127+
], JSON_THROW_ON_ERROR);
127128

128129
if (!$computergroup_dynamic->getFromDBByCrit($input)) {
129130
$input['search'] = $search;

inc/computergroup.class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ public function countDynamicItem()
198198

199199
$iterator = $DB->request($params);
200200
foreach ($iterator as $computergroup_dynamic) {
201-
$search_params = Search::manageParams('Computer', unserialize($computergroup_dynamic['search']));
201+
$search_params = Search::manageParams('Computer', json_decode($computergroup_dynamic['search'], true, 512, JSON_THROW_ON_ERROR));
202202
$data = Search::prepareDatasForSearch('Computer', $search_params);
203203
Search::constructSQL($data);
204204
Search::constructData($data);

inc/computergroup.class.php.orig

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
<?php
2+
3+
/**
4+
* -------------------------------------------------------------------------
5+
* DatabaseInventory plugin for GLPI
6+
* -------------------------------------------------------------------------
7+
*
8+
* LICENSE
9+
*
10+
* This file is part of DatabaseInventory.
11+
*
12+
* DatabaseInventory is free software; you can redistribute it and/or modify
13+
* it under the terms of the GNU General Public License as published by
14+
* the Free Software Foundation; either version 3 of the License, or
15+
* (at your option) any later version.
16+
*
17+
* DatabaseInventory is distributed in the hope that it will be useful,
18+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
* GNU General Public License for more details.
21+
*
22+
* You should have received a copy of the GNU General Public License
23+
* along with DatabaseInventory. If not, see <http://www.gnu.org/licenses/>.
24+
* -------------------------------------------------------------------------
25+
* @copyright Copyright (C) 2021-2023 by Teclib'.
26+
* @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html
27+
* @link https://services.glpi-network.com
28+
* -------------------------------------------------------------------------
29+
*/
30+
31+
use Glpi\Application\View\TemplateRenderer;
32+
33+
/**
34+
* -------------------------------------------------------------------------
35+
* DatabaseInventory plugin for GLPI
36+
* -------------------------------------------------------------------------
37+
*
38+
* LICENSE
39+
*
40+
* This file is part of DatabaseInventory.
41+
*
42+
* DatabaseInventory is free software; you can redistribute it and/or modify
43+
* it under the terms of the GNU General Public License as published by
44+
* the Free Software Foundation; either version 3 of the License, or
45+
* (at your option) any later version.
46+
*
47+
* DatabaseInventory is distributed in the hope that it will be useful,
48+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
49+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50+
* GNU General Public License for more details.
51+
*
52+
* You should have received a copy of the GNU General Public License
53+
* along with DatabaseInventory. If not, see <http://www.gnu.org/licenses/>.
54+
* -------------------------------------------------------------------------
55+
* @copyright Copyright (C) 2021-2023 by Teclib'.
56+
* @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html
57+
* @link https://services.glpi-network.com
58+
* -------------------------------------------------------------------------
59+
*/
60+
61+
class PluginDatabaseinventoryComputerGroup extends CommonDBTM
62+
{
63+
public $dohistory = true;
64+
public static $rightname = 'database_inventory';
65+
66+
public static function getTypeName($nb = 0)
67+
{
68+
return _n('Computer Group', 'Computers Group', $nb, 'databaseinventory');
69+
}
70+
71+
public static function canCreate()
72+
{
73+
return Session::haveRight(static::$rightname, UPDATE);
74+
}
75+
76+
public static function canPurge()
77+
{
78+
return Session::haveRight(static::$rightname, UPDATE);
79+
}
80+
81+
public function defineTabs($options = [])
82+
{
83+
$ong = [];
84+
$this->addDefaultFormTab($ong)
85+
->addStandardTab('PluginDatabaseinventoryComputerGroupDynamic', $ong, $options)
86+
->addStandardTab('PluginDatabaseinventoryComputerGroupStatic', $ong, $options)
87+
->addStandardTab('Log', $ong, $options);
88+
89+
return $ong;
90+
}
91+
92+
public function rawSearchOptions()
93+
{
94+
$tab = parent::rawSearchOptions();
95+
96+
$tab[] = [
97+
'id' => '2',
98+
'table' => $this->getTable(),
99+
'field' => 'id',
100+
'name' => __('ID'),
101+
'massiveaction' => false, // implicit field is id
102+
'datatype' => 'number',
103+
];
104+
105+
$tab[] = [
106+
'id' => '3',
107+
'table' => $this->getTable(),
108+
'field' => 'comment',
109+
'name' => __('Comment'),
110+
'datatype' => 'text',
111+
];
112+
113+
$tab[] = [
114+
'id' => '5',
115+
'table' => PluginDatabaseinventoryComputerGroupDynamic::getTable(),
116+
'field' => 'search',
117+
'name' => __('Number of dynamic items', 'databaseinventory'),
118+
'nosearch' => true,
119+
'massiveaction' => false,
120+
'forcegroupby' => true,
121+
'additionalfields' => ['id'],
122+
'joinparams' => ['jointype' => 'child'],
123+
'datatype' => 'specific',
124+
];
125+
126+
$tab[] = [
127+
'id' => '6',
128+
'table' => PluginDatabaseinventoryComputerGroupStatic::getTable(),
129+
'field' => 'id',
130+
'name' => __('Number of static items', 'databaseinventory'),
131+
'forcegroupby' => true,
132+
'usehaving' => true,
133+
'nosearch' => true,
134+
'datatype' => 'count',
135+
'massiveaction' => false,
136+
'joinparams' => ['jointype' => 'child'],
137+
];
138+
139+
$tab[] = [
140+
'id' => '7',
141+
'table' => PluginDatabaseinventoryComputerGroupDynamic::getTable(),
142+
'field' => '_virtual_dynamic_list',
143+
'name' => __('List of dynamic items', 'databaseinventory'),
144+
'massiveaction' => false,
145+
'forcegroupby' => true,
146+
'nosearch' => true,
147+
'additionalfields' => ['id', 'search'],
148+
'searchtype' => ['equals', 'notequals'],
149+
'joinparams' => ['jointype' => 'child'],
150+
'datatype' => 'specific',
151+
];
152+
153+
$tab[] = [
154+
'id' => '8',
155+
'table' => Computer::getTable(),
156+
'field' => 'name',
157+
'datatype' => 'itemlink',
158+
'name' => __('List of static items', 'databaseinventory'),
159+
'forcegroupby' => true,
160+
'massiveaction' => false,
161+
'joinparams' => [
162+
'beforejoin' => [
163+
'table' => PluginDatabaseinventoryComputerGroupStatic::getTable(),
164+
'joinparams' => [
165+
'jointype' => 'child',
166+
],
167+
],
168+
],
169+
];
170+
171+
return $tab;
172+
}
173+
174+
public function showForm($ID, array $options = [])
175+
{
176+
$this->initForm($ID, $options);
177+
TemplateRenderer::getInstance()->display(
178+
'@databaseinventory/computergroup.html.twig',
179+
[
180+
'item' => $this,
181+
],
182+
);
183+
184+
return true;
185+
}
186+
187+
public function countDynamicItem()
188+
{
189+
/** @var DBmysql $DB */
190+
global $DB;
191+
$count = 0;
192+
193+
$params = [
194+
'SELECT' => '*',
195+
'FROM' => PluginDatabaseinventoryComputerGroupDynamic::getTable(),
196+
'WHERE' => ['plugin_databaseinventory_computergroups_id' => $this->fields['id']],
197+
];
198+
199+
$iterator = $DB->request($params);
200+
foreach ($iterator as $computergroup_dynamic) {
201+
$search_params = Search::manageParams('Computer', unserialize($computergroup_dynamic['search']));
202+
$data = Search::prepareDatasForSearch('Computer', $search_params);
203+
Search::constructSQL($data);
204+
Search::constructData($data);
205+
$count += $data['data']['totalcount'];
206+
}
207+
208+
return $count;
209+
}
210+
211+
public function countStaticItem()
212+
{
213+
/** @var DBmysql $DB */
214+
global $DB;
215+
216+
$params = [
217+
'SELECT' => '*',
218+
'FROM' => PluginDatabaseinventoryComputerGroupStatic::getTable(),
219+
'WHERE' => ['plugin_databaseinventory_computergroups_id' => $this->fields['id']],
220+
];
221+
222+
$iterator = $DB->request($params);
223+
$count = count($iterator);
224+
225+
return $count;
226+
}
227+
228+
public static function install(Migration $migration)
229+
{
230+
/** @var DBmysql $DB */
231+
global $DB;
232+
233+
$default_charset = DBConnection::getDefaultCharset();
234+
$default_collation = DBConnection::getDefaultCollation();
235+
$default_key_sign = DBConnection::getDefaultPrimaryKeySignOption();
236+
237+
$table = self::getTable();
238+
if (!$DB->tableExists($table)) {
239+
$migration->displayMessage("Installing $table");
240+
$query = <<<SQL
241+
CREATE TABLE IF NOT EXISTS `$table` (
242+
`id` int {$default_key_sign} NOT NULL AUTO_INCREMENT,
243+
`name` varchar(255) DEFAULT NULL,
244+
`comment` text,
245+
`date_creation` timestamp NULL DEFAULT NULL,
246+
`date_mod` timestamp NULL DEFAULT NULL,
247+
PRIMARY KEY (`id`),
248+
KEY `name` (`name`),
249+
KEY `date_creation` (`date_creation`),
250+
KEY `date_mod` (`date_mod`)
251+
) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;
252+
SQL;
253+
$DB->doQuery($query);
254+
255+
// install default display preferences
256+
$migration->updateDisplayPrefs(
257+
[
258+
PluginDatabaseinventoryComputerGroup::class => [3, 5, 6],
259+
],
260+
);
261+
} else {
262+
// Fix `comment` field type (was a varchar prior to v1.0.0)
263+
$migration->dropKey($table, 'comment');
264+
$migration->changeField($table, 'comment', 'comment', 'text');
265+
}
266+
}
267+
268+
public static function uninstall(Migration $migration)
269+
{
270+
/** @var DBmysql $DB */
271+
global $DB;
272+
$table = self::getTable();
273+
if ($DB->tableExists($table)) {
274+
$DB->doQuery('DROP TABLE IF EXISTS `' . self::getTable() . '`');
275+
}
276+
}
277+
278+
public static function getIcon()
279+
{
280+
return 'ti ti-sitemap';
281+
}
282+
283+
public function post_purgeItem()
284+
{
285+
$c_dynamic = new PluginDatabaseinventoryComputerGroupDynamic();
286+
$c_dynamic->deleteByCriteria(['plugin_databaseinventory_computergroups_id' => $this->fields['id']]);
287+
288+
$c_static = new PluginDatabaseinventoryComputerGroupStatic();
289+
$c_static->deleteByCriteria(['plugin_databaseinventory_computergroups_id' => $this->fields['id']]);
290+
291+
$databaseparam_credential = new PluginDatabaseinventoryDatabaseParam_ComputerGroup();
292+
$databaseparam_credential->deleteByCriteria(['plugin_databaseinventory_computergroups_id' => $this->fields['id']]);
293+
}
294+
}

inc/computergroupdynamic.class.php

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,9 @@ public static function getSpecificValueToDisplay($field, $values, array $options
9090
$value = ' ';
9191
$out = ' ';
9292
if (strpos($values['id'], Search::NULLVALUE) === false) {
93-
$search_params = Search::manageParams('Computer', unserialize($values['search']));
93+
$search_params = Search::manageParams('Computer',
94+
json_decode($values['search'], true, 512, JSON_THROW_ON_ERROR)
95+
);
9496
$data = Search::prepareDatasForSearch('Computer', $search_params);
9597
Search::constructSQL($data);
9698
Search::constructData($data);
@@ -158,7 +160,9 @@ public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $
158160

159161
private function countDynamicItems()
160162
{
161-
$search_params = Search::manageParams('Computer', unserialize($this->fields['search']));
163+
$search_params = Search::manageParams('Computer',
164+
json_decode($this->fields['search'], true, 512, JSON_THROW_ON_ERROR)
165+
);
162166
$data = Search::prepareDatasForSearch('Computer', $search_params);
163167
Search::constructSQL($data);
164168
Search::constructData($data);
@@ -170,7 +174,7 @@ private function countDynamicItems()
170174
public function isDynamicSearchMatchComputer(Computer $computer)
171175
{
172176
// add new criteria to force computer ID
173-
$search = unserialize($this->fields['search']);
177+
$search = json_decode($this->fields['search']);
174178
$search['criteria'][] = [
175179
'link' => 'AND',
176180
'field' => 2, // computer ID
@@ -208,7 +212,9 @@ private static function showForItem(PluginDatabaseinventoryComputerGroup $comput
208212
'plugin_databaseinventory_computergroups_id' => $ID,
209213
])
210214
) {
211-
$p = $search_params = Search::manageParams('Computer', unserialize($computergroup_dynamic->fields['search']));
215+
$p = Search::manageParams('Computer',
216+
json_decode($computergroup_dynamic->fields['search'], true, 512, JSON_THROW_ON_ERROR)
217+
);
212218
$firsttime = false;
213219
} else {
214220
// retrieve filter value from search if exist and reset it
@@ -278,6 +284,34 @@ public static function install(Migration $migration)
278284
) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;
279285
SQL;
280286
$DB->doQuery($query);
287+
} else {
288+
// search field migration from serialized to json
289+
$result = $DB->doQuery("SELECT `id`, `search` FROM `" . $table . "` WHERE `search` NOT LIKE '{%'");
290+
291+
while ($data = $DB->fetchAssoc($result)) {
292+
$id = $data['id'];
293+
$search = $data['search'];
294+
$json_search = json_encode([]); // default value in case of error
295+
296+
try {
297+
$unserialized = @unserialize($search, ['allowed_classes' => false]);
298+
299+
if ($unserialized !== false) {
300+
$json_search = json_encode($unserialized, JSON_THROW_ON_ERROR);
301+
}
302+
} catch (Throwable $e) {
303+
$migration->displayMessage(
304+
"DatabaseInventory - Invalid serialized data for DynamicGroup ID {$id}, data will be reset."
305+
);
306+
continue;
307+
}
308+
309+
$DB->update(
310+
$table,
311+
['search' => $json_search],
312+
['id' => $id]
313+
);
314+
}
281315
}
282316
}
283317

0 commit comments

Comments
 (0)