Skip to content

Commit c1dff13

Browse files
committed
allow choosing glpi type when importing or merging mobile devices
1 parent 6da31da commit c1dff13

File tree

5 files changed

+91
-38
lines changed

5 files changed

+91
-38
lines changed

ajax/import.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
if (isset($_REQUEST['import_ids']) && is_array($_REQUEST['import_ids'])) {
5656
// Get data for each item to import
5757
$toimport = $DB->request([
58-
'SELECT' => ['type', 'jamf_type', 'jamf_items_id'],
58+
'SELECT' => ['id', 'type', 'jamf_type', 'jamf_items_id'],
5959
'FROM' => PluginJamfImport::getTable(),
6060
'WHERE' => [
6161
'id' => $_REQUEST['import_ids']
@@ -66,10 +66,11 @@
6666
PluginJamfComputerSync::syncExtensionAttributeDefinitions();
6767
// Import the requested device(s)
6868
foreach ($toimport as $data) {
69+
$glpi_itemtype = $_REQUEST['itemtype_overrides'][$data['id']] ?? $data['type'];
6970
if ($data['jamf_type'] === 'MobileDevice') {
70-
PluginJamfMobileSync::import($data['type'], $data['jamf_items_id']);
71+
PluginJamfMobileSync::import($glpi_itemtype, $data['jamf_items_id']);
7172
} else {
72-
PluginJamfComputerSync::import($data['type'], $data['jamf_items_id']);
73+
PluginJamfComputerSync::import($glpi_itemtype, $data['jamf_items_id']);
7374
}
7475
}
7576
} else {

ajax/merge.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@
5353
// Trigger extension attribute definition sync
5454
PluginJamfMobileSync::syncExtensionAttributeDefinitions();
5555
PluginJamfComputerSync::syncExtensionAttributeDefinitions();
56+
$supported_glpi_types = [
57+
'Computer' => PluginJamfComputerSync::getSupportedGlpiItemtypes(),
58+
'MobileDevice' => PluginJamfMobileSync::getSupportedGlpiItemtypes()
59+
];
5660
// An array of item IDs is required
5761
if (isset($_REQUEST['item_ids']) && is_array($_REQUEST['item_ids'])) {
5862
$failures = 0;
@@ -64,7 +68,7 @@
6468
$jamf_id = $data['jamf_id'];
6569
$itemtype = $data['itemtype'];
6670

67-
if (($itemtype !== 'Computer') && ($itemtype !== 'Phone')) {
71+
if (!in_array($itemtype, $supported_glpi_types[$data['jamf_type']])) {
6872
// Invalid itemtype for a mobile device
6973
throw new RuntimeException('Invalid itemtype!');
7074
}

front/merge.php

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -63,35 +63,46 @@
6363
$linked[$data['itemtype']][] = $data;
6464
}
6565

66+
$supported_glpi_types = [
67+
'Computer' => PluginJamfComputerSync::getSupportedGlpiItemtypes(),
68+
'MobileDevice' => PluginJamfMobileSync::getSupportedGlpiItemtypes()
69+
];
70+
6671
foreach ($pending as &$data) {
67-
$itemtype = $data['type'];
68-
/** @var CommonDBTM $item */
69-
$item = new $itemtype();
70-
$jamftype = ('PluginJamf' . $data['jamf_type']);
71-
$guesses = $DB->request([
72-
'SELECT' => ['id'],
73-
'FROM' => $itemtype::getTable(),
74-
'WHERE' => [
75-
'OR' => [
76-
'uuid' => $data['udid'],
77-
'name' => Sanitizer::sanitize($data['name'])
72+
$queries = [];
73+
foreach ($supported_glpi_types[$data['jamf_type']] as $type) {
74+
$queries[] = [
75+
'SELECT' => [
76+
new QueryExpression($DB::quoteValue($type) . ' AS ' . $DB::quoteName('itemtype')),
77+
'id'
78+
],
79+
'FROM' => $type::getTable(),
80+
'WHERE' => [
81+
'OR' => [
82+
'uuid' => $data['udid'],
83+
'name' => Sanitizer::sanitize($data['name'])
84+
],
85+
'is_deleted' => 0,
86+
'is_template' => 0
7887
],
79-
'is_deleted' => 0,
80-
'is_template' => 0
81-
],
82-
'ORDER' => new QueryExpression("CASE WHEN uuid='" . $data['udid'] . "' THEN 0 ELSE 1 END"),
83-
'LIMIT' => 1
84-
]);
85-
if (count($guesses)) {
86-
$data['guessed_item'] = $guesses->current()['id'];
87-
} else {
88-
$data['guessed_item'] = 0;
88+
'ORDER' => new QueryExpression("CASE WHEN uuid='" . $data['udid'] . "' THEN 0 ELSE 1 END"),
89+
'LIMIT' => 1
90+
];
91+
}
92+
$guesses = $DB->request(new QueryUnion($queries));
93+
$data['guessed_item'] = null;
94+
foreach ($guesses as $guess) {
95+
$data['guessed_item'][$guess['itemtype']] = $guess['id'];
8996
}
9097
}
9198

9299
TemplateRenderer::getInstance()->display('@jamf/merge.html.twig', [
93100
'pending' => $pending,
94101
'total_count' => $importcount,
95-
'linked' => $linked
102+
'linked' => $linked,
103+
'supported_glpi_types' => array_map(
104+
static fn ($ts) => array_combine($ts, array_map(static fn ($t) => $t::getTypeName(1), $ts)),
105+
$supported_glpi_types
106+
)
96107
]);
97108
Html::footer();

templates/import.html.twig

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
* -------------------------------------------------------------------------
2929
*/
3030
#}
31+
{% import 'components/form/fields_macros.html.twig' as fields %}
3132

3233
<form>
3334
{{ include('components/pager.html.twig', {
@@ -57,14 +58,26 @@
5758
{% set import_checkbox %}
5859
<input type="checkbox" name="import_{{ data.id }}" class="form-check-input massive_action_checkbox">
5960
{% endset %}
60-
<tr>
61+
<tr data-import-id="{{ data.id }}">
6162
<td>{{ import_checkbox }}</td>
6263
<td>{{ data.jamf_items_id }}</td>
6364
<td>{{ data.jamf_type }}</td>
6465
<td>
6566
<a href="{{ call('PluginJamf' ~ data.jamf_type ~ '::getJamfDeviceURL', [data.jamf_items_id]) }}">{{ data.name }}</a>
6667
</td>
67-
<td>{{ data.type }}</td>
68+
{% if data.jamf_type == 'MobileDevice' %}
69+
<td>
70+
{{ fields.dropdownArrayField('glpi_type', data.type, {
71+
'Phone': 'Phone'|itemtype_name,
72+
'Computer': 'Computer'|itemtype_name,
73+
}, null, {
74+
no_label: true,
75+
full_width: true,
76+
}) }}
77+
</td>
78+
{% else %}
79+
<td>{{ data.type|itemtype_name }}</td>
80+
{% endif %}
6881
<td class="{{ data.udid is empty ? 'font-italic' : '' }}">
6982
{{ data.udid is not empty ? data.udid : _x('message', 'Not collected during discovery', 'jamf') }}
7083
</td>
@@ -90,12 +103,19 @@
90103
const import_ids = $(':checkbox:checked').filter(':not([name^="_checkall"])').map(function() {
91104
return this.name.replace("import","").substring(1).split('_');
92105
}).toArray();
106+
const itemtype_overrides = {};
107+
$('select[name="glpi_type"]').each((i, e) => {
108+
const itemtype = $(e).val();
109+
const id = $(e).closest('tr').attr('data-import-id');
110+
itemtype_overrides[id] = itemtype;
111+
});
93112
$.ajax({
94113
type: "POST",
95114
url: "{{ get_plugin_web_dir('jamf') }}/ajax/import.php",
96115
data: {
97116
action: "import",
98-
import_ids: import_ids
117+
import_ids: import_ids,
118+
itemtype_overrides: itemtype_overrides
99119
},
100120
contentType: 'application/json',
101121
beforeSend: () => {

templates/merge.html.twig

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,31 @@
5858
<td>
5959
<a href="{{ call('PluginJamf' ~ data.jamf_type ~ '::getJamfDeviceURL', [data.jamf_items_id]) }}">{{ data.name }}</a>
6060
</td>
61-
<td>{{ data.type }}</td>
61+
<td>
62+
{% if supported_glpi_types[data.jamf_type]|length > 0 %}
63+
{{ fields.dropdownArrayField('glpi_type', data.type, supported_glpi_types[data.jamf_type], null, {
64+
no_label: true,
65+
full_width: true,
66+
}) }}
67+
{% else %}
68+
{{ data.type|itemtype_name }}
69+
{% endif %}
70+
</td>
6271
<td>{{ data.jamf_type }}</td>
6372
<td class="{{ data.udid is empty ? 'font-italic' : '' }}">
6473
{{ data.udid is not empty ? data.udid : _x('message', 'Not collected during discovery', 'jamf') }}
6574
</td>
6675
<td>{{ data.date_discover|formatted_datetime }}</td>
6776
<td>
68-
{{ fields.dropdownField(data.type, 'items_id', data.guessed_item, null, {
69-
no_label: true,
70-
full_width: true,
71-
used: linked[data.type]|default([])|column('items_id')
72-
}) }}
77+
{% for glpi_type in supported_glpi_types[data.jamf_type] %}
78+
<span class="{{ glpi_type != data.type ? 'd-none' : '' }}" data-itemtype="{{ glpi_type }}">
79+
{{ fields.dropdownField(glpi_type, 'items_id', data.guessed_item[glpi_type], null, {
80+
no_label: true,
81+
full_width: true,
82+
used: linked[glpi_type]|default([])|column('items_id'),
83+
}) }}
84+
</span>
85+
{% endfor %}
7386
</td>
7487
</tr>
7588
{% endfor %}
@@ -93,12 +106,11 @@
93106
for (let i = 1; i < row_count; i++) {
94107
const row = table.rows[i];
95108
const jamf_id = row.cells[0].innerText;
96-
const itemtype = row.cells[2].innerText;
109+
const itemtype = $(row.cells[2]).find('select')[0].value;
97110
const jamf_type = row.cells[3].innerText;
98-
const glpi_sel = $(row.cells[6]).find('select')[0];
111+
const glpi_sel = $(row.cells[6]).find('span[data-itemtype]:not(.d-none) select')[0];
99112
const glpi_id = glpi_sel.value;
100113
if (glpi_id && glpi_id > 0) {
101-
data = [];
102114
post_data[glpi_id] = {'itemtype': itemtype, 'jamf_id': jamf_id, 'jamf_type': jamf_type};
103115
}
104116
}
@@ -115,6 +127,11 @@
115127
}
116128
});
117129
}
130+
$('select[name="glpi_type"]').on('change', (e) => {
131+
const selection = $(e.target).val();
132+
$(e.target).closest('tr').find('span[data-itemtype]').addClass('d-none');
133+
$(e.target).closest('tr').find('span[data-itemtype="' + selection + '"]').removeClass('d-none');
134+
});
118135
</script>
119136
</div>
120137
</form>

0 commit comments

Comments
 (0)