Skip to content

Commit 3f51fbd

Browse files
committed
fix(issue): sync issue fails when a ticket has several validators
if a ticket has several validators, the sync issue fails to recreate the row the HAVING COUNT() clause finds 2 rows instead of 1 The solution is to drop the user and group validators and find them dynamically with JOIN. this also allows to find all ticket validators
1 parent 1f526d8 commit 3f51fbd

7 files changed

+260
-65
lines changed

hook.php

+33-17
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,16 @@ function plugin_formcreator_addDefaultJoin($itemtype, $ref_table, &$already_link
9898
$join .= PluginAdvformCommon::addDefaultJoin($itemtype, $ref_table, $already_link_tables);
9999
} else {
100100
$issueSo = Search::getOptions($itemtype);
101+
$join .= Search::addLeftJoin(
102+
$itemtype,
103+
$ref_table,
104+
$already_link_tables,
105+
$issueSo[9]['table'],
106+
'users_id_validator',
107+
0,
108+
0,
109+
$issueSo[9]['joinparams']
110+
);
101111
$join .= Search::addLeftJoin(
102112
$itemtype,
103113
$ref_table,
@@ -108,7 +118,16 @@ function plugin_formcreator_addDefaultJoin($itemtype, $ref_table, &$already_link
108118
0,
109119
$issueSo[11]['joinparams']
110120
);
111-
121+
$join .= Search::addLeftJoin(
122+
$itemtype,
123+
$ref_table,
124+
$already_link_tables,
125+
$issueSo[16]['table'],
126+
'groups_id_validator',
127+
0,
128+
0,
129+
$issueSo[16]['joinparams']
130+
);
112131
}
113132
break;
114133

@@ -145,12 +164,11 @@ function plugin_formcreator_addDefaultWhere($itemtype) {
145164
$condition .= ' OR ';
146165
}
147166
// condition where current user is a validator of the issue
148-
if (Plugin::isPluginActive(PLUGIN_FORMCREATOR_ADVANCED_VALIDATION)) {
149-
$complexJoinId = Search::computeComplexJoinID(Search::getOptions($itemtype)[9]['joinparams']);
150-
$condition .= "`glpi_users_$complexJoinId`.`id` = '$currentUser'";
151-
} else {
152-
$condition .= "`glpi_plugin_formcreator_issues`.`users_id_validator` = '$currentUser'";
153-
}
167+
// Search optin ID 9 is either from Formcreator, either from AdvForms
168+
$issueSearchOptions = Search::getOptions($itemtype);
169+
$complexJoinId = Search::computeComplexJoinID($issueSearchOptions[9]['joinparams']);
170+
$colname = $issueSearchOptions[9]['linkfield'];
171+
$condition .= "`glpi_users_${colname}_$complexJoinId`.`id` = '$currentUser'";
154172

155173
// condition where current user is a member of a validator group of the issue
156174
$groupList = [];
@@ -159,16 +177,14 @@ function plugin_formcreator_addDefaultWhere($itemtype) {
159177
}
160178
if (count($groupList) > 0) {
161179
$groupList = implode("', '", $groupList);
162-
if (Plugin::isPluginActive(PLUGIN_FORMCREATOR_ADVANCED_VALIDATION)) {
163-
$complexJoinId = Search::computeComplexJoinID(Search::getOptions($itemtype)[9]['joinparams']);
164-
$condition .= " OR `glpi_groups_$complexJoinId`.`id` IN ('$groupList')";
165-
} else {
166-
$condition .= " OR `glpi_plugin_formcreator_issues`.`groups_id_validator` IN ('$groupList')";
167-
}
180+
// Search option ID 16 is either from Formcreator, either from AdvForms
181+
$complexJoinId = Search::computeComplexJoinID($issueSearchOptions[16]['joinparams']);
182+
$colname = $issueSearchOptions[16]['linkfield'];
183+
$condition .= " OR `glpi_groups_${colname}_$complexJoinId`.`id` IN ('$groupList')";
168184
}
169185

170186
// condition where current user is a validator of a issue of type ticket
171-
$complexJoinId = Search::computeComplexJoinID(Search::getOptions($itemtype)[11]['joinparams']);
187+
$complexJoinId = Search::computeComplexJoinID($issueSearchOptions[11]['joinparams']);
172188
$condition .= " OR `glpi_users_users_id_validate_$complexJoinId`.`id` = '$currentUser'";
173189
// Add users_id_recipient
174190
$condition .= " OR `glpi_plugin_formcreator_issues`.`users_id_recipient` = $currentUser ";
@@ -368,7 +384,7 @@ function plugin_formcreator_hook_add_ticket(CommonDBTM $item) {
368384
'name' => $issueName,
369385
'display_id' => 't_' . $item->getID(),
370386
'items_id' => $item->getID(),
371-
'itemtype' => 'Ticket',
387+
'itemtype' => Ticket::class,
372388
'status' => $validationStatus,
373389
'date_creation' => $item->fields['date'],
374390
'date_mod' => $item->fields['date_mod'],
@@ -417,7 +433,7 @@ function plugin_formcreator_hook_update_ticket(CommonDBTM $item) {
417433
'id' => $issue->getID(),
418434
'items_id' => $id,
419435
'display_id' => "t_$id",
420-
'itemtype' => 'Ticket',
436+
'itemtype' => Ticket::class,
421437
'name' => $issueName,
422438
'status' => $validationStatus,
423439
'date_creation' => $item->fields['date'],
@@ -581,7 +597,7 @@ function plugin_formcreator_dynamicReport($params) {
581597
case PluginFormcreatorFormAnswer::class;
582598
if ($url = parse_url($_SERVER['HTTP_REFERER'])) {
583599
if (strpos($url['path'],
584-
Toolbox::getItemTypeFormURL("PluginFormcreatorForm")) !== false) {
600+
Toolbox::getItemTypeFormURL(PluginFormcreatorForm::class)) !== false) {
585601
parse_str($url['query'], $query);
586602
if (isset($query['id'])) {
587603
$item = PluginFormcreatorCommon::getForm();

inc/formanswer.class.php

-4
Original file line numberDiff line numberDiff line change
@@ -1418,8 +1418,6 @@ public function createIssue() {
14181418
'entities_id' => $this->fields['entities_id'],
14191419
'is_recursive' => $this->fields['is_recursive'],
14201420
'requester_id' => $this->fields['requester_id'],
1421-
'users_id_validator' => $this->fields['users_id_validator'],
1422-
'groups_id_validator'=> $this->fields['groups_id_validator'],
14231421
'comment' => '',
14241422
]);
14251423

@@ -1522,8 +1520,6 @@ private function updateIssue() {
15221520
'entities_id' => $this->fields['entities_id'],
15231521
'is_recursive' => $this->fields['is_recursive'],
15241522
'requester_id' => $this->fields['requester_id'],
1525-
'users_id_validator' => $this->fields['users_id_validator'],
1526-
'groups_id_validator'=> $this->fields['groups_id_validator'],
15271523
'comment' => '',
15281524
]);
15291525

inc/issue.class.php

+78-31
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,6 @@ public static function getSyncIssuesRequest() : AbstractQuery {
105105
'entities_id as entities_d',
106106
'is_recursive as is_recursive',
107107
'requester_id as requester_id',
108-
'users_id_validator as users_id_validator',
109-
'groups_id_validator as groups_id_validator',
110108
'comment as comment',
111109
'requester_id as users_id_recipient'
112110
],
@@ -145,16 +143,13 @@ public static function getSyncIssuesRequest() : AbstractQuery {
145143
new QueryExpression("CONCAT('t_', `$ticketTable`.`id`) as `display_id`"),
146144
"$ticketTable.id as items_id",
147145
new QueryExpression("'" . Ticket::getType() . "' as `itemtype`"),
148-
new QueryExpression("IF(`$ticketValidationTable`.`status` IS NULL,
146+
new QueryExpression("IF(`$ticketTable`.`global_validation` IN ('" . CommonITILValidation::NONE . "', '" . CommonITILValidation::ACCEPTED . "'),
149147
`$ticketTable`.`status`,
150-
IF(`$ticketTable`.`global_validation` IN ('" . CommonITILValidation::NONE . "', '" . CommonITILValidation::ACCEPTED . "'),
148+
IF(`$ticketTable`.`status` IN ('" . CommonITILObject::SOLVED . "', '" . CommonITILObject::CLOSED . "'),
151149
`$ticketTable`.`status`,
152-
IF(`$ticketTable`.`status` IN ('" . CommonITILObject::SOLVED . "', '" . CommonITILObject::CLOSED . "'),
153-
`$ticketTable`.`status`,
154-
IF(`$ticketTable`.`global_validation` = '" . CommonITILValidation::WAITING . "',
155-
'" . PluginFormcreatorFormAnswer::STATUS_WAITING . "',
156-
'" . PluginFormcreatorFormAnswer::STATUS_REFUSED . "'
157-
)
150+
IF(`$ticketTable`.`global_validation` = '" . CommonITILValidation::WAITING . "',
151+
'" . PluginFormcreatorFormAnswer::STATUS_WAITING . "',
152+
'" . PluginFormcreatorFormAnswer::STATUS_REFUSED . "'
158153
)
159154
)
160155
) AS `status`"),
@@ -165,8 +160,6 @@ public static function getSyncIssuesRequest() : AbstractQuery {
165160
],
166161
new QueryExpression('0 as is_recursive'),
167162
new QueryExpression("COALESCE(`$ticketUserTable`.`users_id`, 0) as `requester_id`"),
168-
new QueryExpression("COALESCE(`$ticketValidationTable`.`users_id_validate`, 0) as `users_id_validator`"),
169-
new QueryExpression('0 as groups_id_validator'),
170163
"$ticketTable.content as comment",
171164
'users_id_recipient as users_id_recipient'
172165
],
@@ -198,12 +191,6 @@ public static function getSyncIssuesRequest() : AbstractQuery {
198191
$ticketUserTable => $ticketFk,
199192
],
200193
],
201-
$ticketValidationTable => [
202-
'FKEY' => [
203-
$ticketTable => 'id',
204-
$ticketValidationTable => $ticketFk,
205-
],
206-
],
207194
],
208195
'WHERE' => [
209196
"$ticketTable.is_deleted" => 0,
@@ -219,7 +206,7 @@ public static function getSyncIssuesRequest() : AbstractQuery {
219206
'INNER JOIN' => [$itemTicketTable => $query2['LEFT JOIN'][$itemTicketTable]],
220207
'LEFT JOIN' => [
221208
$query2['LEFT JOIN'][0], // This is the TABLE => [...] subquery
222-
$ticketValidationTable => $query2['LEFT JOIN'][$ticketValidationTable],
209+
// $ticketValidationTable => $query2['LEFT JOIN'][$ticketValidationTable],
223210
],
224211
'WHERE' => $query2['WHERE'],
225212
'GROUPBY' => ["$itemTicketTable.items_id"],
@@ -521,7 +508,6 @@ public function rawSearchOptions() {
521508
'name' => __('Name'),
522509
'datatype' => 'itemlink',
523510
'massiveaction' => false,
524-
'forcegroupby' => true,
525511
'additionalfields' => [
526512
'0' => 'display_id'
527513
]
@@ -608,14 +594,22 @@ public function rawSearchOptions() {
608594
} else {
609595
$newtab = [
610596
'id' => '9',
611-
'table' => 'glpi_users',
597+
'table' => User::getTable(),
612598
'field' => 'name',
613599
'linkfield' => 'users_id_validator',
614600
'name' => __('Form approver', 'formcreator'),
615601
'datatype' => 'dropdown',
616-
'massiveaction' => false
602+
'massiveaction' => false,
603+
'joinparams' => [
604+
'beforejoin' => [
605+
'table' => PluginFormcreatorFormAnswer::getTable(),
606+
'joinparams' => [
607+
'jointype' => 'itemtype_item_revert',
608+
'specific_itemtype' => PluginFormcreatorFormAnswer::class,
609+
]
610+
],
611+
],
617612
];
618-
619613
}
620614
if (!Session::isCron() // no filter for cron
621615
&& Session::getCurrentInterface() == 'helpdesk') {
@@ -640,12 +634,12 @@ public function rawSearchOptions() {
640634
'field' => 'name',
641635
'linkfield' => 'users_id_validate',
642636
'name' => __('Ticket approver', 'formcreator'),
643-
'datatype' => 'dropdown',
637+
'datatype' => 'itemlink',
644638
'right' => [
645639
'0' => 'validate_request',
646640
'1' => 'validate_incident'
647641
],
648-
'forcegroupby' => false,
642+
'forcegroupby' => true,
649643
'massiveaction' => false,
650644
'joinparams' => [
651645
'beforejoin' => [
@@ -663,6 +657,12 @@ public function rawSearchOptions() {
663657
],
664658
]
665659
];
660+
if (version_compare(GLPI_VERSION, '10.1') >= 0) {
661+
$newtab['linkfield'] = 'items_id_target';
662+
$newtab['condition'] = [
663+
'REFTABLE.itemtype_target' => User::class,
664+
];
665+
}
666666
if (!Session::isCron() // no filter for cron
667667
&& Session::getCurrentInterface() == 'helpdesk') {
668668
$newtab['right'] = 'id';
@@ -675,7 +675,6 @@ public function rawSearchOptions() {
675675
'field' => 'name',
676676
'name' => __('Technician'),
677677
'datatype' => 'dropdown',
678-
'forcegroupby' => true,
679678
'massiveaction' => false,
680679
'nodisplay' => $hide_technician,
681680
'nosearch' => $hide_technician,
@@ -716,7 +715,9 @@ public function rawSearchOptions() {
716715
'beforejoin' => [
717716
'table' => Group_Ticket::getTable(),
718717
'joinparams' => [
719-
'condition' => "AND NEWTABLE.`type` = '2'", // Assign
718+
'condition' => [
719+
'NEWTABLE.type' => CommonITILActor::ASSIGN,
720+
],
720721
'jointype' => 'child',
721722
'beforejoin' => [
722723
'table' => Ticket::getTable(),
@@ -732,17 +733,63 @@ public function rawSearchOptions() {
732733
}
733734

734735
if (Plugin::isPluginActive(PLUGIN_FORMCREATOR_ADVANCED_VALIDATION)) {
735-
$tab[] = PluginAdvformIssue::rawSearchOptionFormApproverGroup();
736+
$newtab = PluginAdvformIssue::rawSearchOptionFormApproverGroup();
736737
} else {
737-
$tab[] = [
738+
$newtab = [
738739
'id' => '16',
739-
'table' => 'glpi_groups',
740+
'table' => Group::getTable(),
740741
'field' => 'completename',
742+
'linkfield' => 'groups_id_validator',
741743
'name' => __('Form approver group', 'formcreator'),
742744
'datatype' => 'itemlink',
743745
'massiveaction' => false,
744-
'linkfield' => 'groups_id_validator',
746+
'joinparams' => [
747+
'beforejoin' => [
748+
'table' => PluginFormcreatorFormAnswer::getTable(),
749+
'joinparams' => [
750+
'jointype' => 'itemtype_item_revert',
751+
'specific_itemtype' => PluginFormcreatorFormAnswer::class,
752+
]
753+
],
754+
],
755+
];
756+
}
757+
$tab[] = $newtab;
758+
759+
if (version_compare(GLPI_VERSION, '10.1') >= 0) {
760+
$newtab = [
761+
'id' => '17',
762+
'table' => Group::getTable(),
763+
'field' => 'name',
764+
'linkfield' => 'items_id_target',
765+
'name' => __('Ticket approver group', 'formcreator'),
766+
'datatype' => 'itemlink',
767+
'condition' => [
768+
'REFTABLE.itemtype_target' => User::class,
769+
],
770+
'right' => [
771+
'0' => 'validate_request',
772+
'1' => 'validate_incident'
773+
],
774+
'forcegroupby' => true,
775+
'massiveaction' => false,
776+
'joinparams' => [
777+
'beforejoin' => [
778+
'table' => TicketValidation::getTable(),
779+
'joinparams' => [
780+
'jointype' => 'child',
781+
'beforejoin' => [
782+
'table' => Ticket::getTable(),
783+
'joinparams' => [
784+
'jointype' => 'itemtype_item_revert',
785+
'specific_itemtype' => Ticket::class,
786+
]
787+
]
788+
]
789+
],
790+
]
745791
];
792+
$tab[] = $newtab;
746793
}
747794

748795
if (Plugin::isPluginActive(PLUGIN_FORMCREATOR_ADVANCED_VALIDATION)) {

install/install.php

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class PluginFormcreatorInstall {
7878
'2.12.1' => '2.12.5',
7979
'2.12.5' => '2.13',
8080
'2.13' => '2.13.1',
81+
'2.13.1' => '2.13.3',
8182
];
8283

8384
protected bool $resyncIssues = false;

install/mysql/plugin_formcreator_2.13.3_empty.sql

+1-5
Original file line numberDiff line numberDiff line change
@@ -294,16 +294,12 @@ CREATE TABLE IF NOT EXISTS `glpi_plugin_formcreator_issues` (
294294
`entities_id` int unsigned NOT NULL DEFAULT '0',
295295
`is_recursive` tinyint(1) NOT NULL DEFAULT '0',
296296
`requester_id` int unsigned NOT NULL DEFAULT '0',
297-
`users_id_validator` int unsigned NOT NULL DEFAULT '0',
298-
`groups_id_validator` int unsigned NOT NULL DEFAULT '0',
299297
`comment` longtext,
300298
`users_id_recipient` int unsigned NOT NULL DEFAULT '0',
301299
PRIMARY KEY (`id`),
302300
INDEX `item` (`itemtype`, `items_id`),
303301
INDEX `entities_id` (`entities_id`),
304-
INDEX `requester_id` (`requester_id`),
305-
INDEX `users_id_validator` (`users_id_validator`),
306-
INDEX `groups_id_validator` (`groups_id_validator`)
302+
INDEX `requester_id` (`requester_id`)
307303
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;
308304
CREATE TABLE IF NOT EXISTS `glpi_plugin_formcreator_items_targettickets` (
309305
`id` int unsigned NOT NULL AUTO_INCREMENT,

0 commit comments

Comments
 (0)