diff --git a/hook.php b/hook.php index a12d973fc..bb6cf4f2a 100644 --- a/hook.php +++ b/hook.php @@ -98,6 +98,16 @@ function plugin_formcreator_addDefaultJoin($itemtype, $ref_table, &$already_link $join .= PluginAdvformCommon::addDefaultJoin($itemtype, $ref_table, $already_link_tables); } else { $issueSo = Search::getOptions($itemtype); + $join .= Search::addLeftJoin( + $itemtype, + $ref_table, + $already_link_tables, + $issueSo[9]['table'], + 'users_id_validator', + 0, + 0, + $issueSo[9]['joinparams'] + ); $join .= Search::addLeftJoin( $itemtype, $ref_table, @@ -108,7 +118,16 @@ function plugin_formcreator_addDefaultJoin($itemtype, $ref_table, &$already_link 0, $issueSo[11]['joinparams'] ); - + $join .= Search::addLeftJoin( + $itemtype, + $ref_table, + $already_link_tables, + $issueSo[16]['table'], + 'groups_id_validator', + 0, + 0, + $issueSo[16]['joinparams'] + ); } break; @@ -145,12 +164,11 @@ function plugin_formcreator_addDefaultWhere($itemtype) { $condition .= ' OR '; } // condition where current user is a validator of the issue - if (Plugin::isPluginActive(PLUGIN_FORMCREATOR_ADVANCED_VALIDATION)) { - $complexJoinId = Search::computeComplexJoinID(Search::getOptions($itemtype)[9]['joinparams']); - $condition .= "`glpi_users_$complexJoinId`.`id` = '$currentUser'"; - } else { - $condition .= "`glpi_plugin_formcreator_issues`.`users_id_validator` = '$currentUser'"; - } + // Search optin ID 9 is either from Formcreator, either from AdvForms + $issueSearchOptions = Search::getOptions($itemtype); + $complexJoinId = Search::computeComplexJoinID($issueSearchOptions[9]['joinparams']); + $colname = $issueSearchOptions[9]['linkfield']; + $condition .= "`glpi_users_${colname}_$complexJoinId`.`id` = '$currentUser'"; // condition where current user is a member of a validator group of the issue $groupList = []; @@ -159,16 +177,14 @@ function plugin_formcreator_addDefaultWhere($itemtype) { } if (count($groupList) > 0) { $groupList = implode("', '", $groupList); - if (Plugin::isPluginActive(PLUGIN_FORMCREATOR_ADVANCED_VALIDATION)) { - $complexJoinId = Search::computeComplexJoinID(Search::getOptions($itemtype)[9]['joinparams']); - $condition .= " OR `glpi_groups_$complexJoinId`.`id` IN ('$groupList')"; - } else { - $condition .= " OR `glpi_plugin_formcreator_issues`.`groups_id_validator` IN ('$groupList')"; - } + // Search option ID 16 is either from Formcreator, either from AdvForms + $complexJoinId = Search::computeComplexJoinID($issueSearchOptions[16]['joinparams']); + $colname = $issueSearchOptions[16]['linkfield']; + $condition .= " OR `glpi_groups_${colname}_$complexJoinId`.`id` IN ('$groupList')"; } // condition where current user is a validator of a issue of type ticket - $complexJoinId = Search::computeComplexJoinID(Search::getOptions($itemtype)[11]['joinparams']); + $complexJoinId = Search::computeComplexJoinID($issueSearchOptions[11]['joinparams']); $condition .= " OR `glpi_users_users_id_validate_$complexJoinId`.`id` = '$currentUser'"; // Add users_id_recipient $condition .= " OR `glpi_plugin_formcreator_issues`.`users_id_recipient` = $currentUser "; @@ -368,7 +384,7 @@ function plugin_formcreator_hook_add_ticket(CommonDBTM $item) { 'name' => $issueName, 'display_id' => 't_' . $item->getID(), 'items_id' => $item->getID(), - 'itemtype' => 'Ticket', + 'itemtype' => Ticket::class, 'status' => $validationStatus, 'date_creation' => $item->fields['date'], 'date_mod' => $item->fields['date_mod'], @@ -417,7 +433,7 @@ function plugin_formcreator_hook_update_ticket(CommonDBTM $item) { 'id' => $issue->getID(), 'items_id' => $id, 'display_id' => "t_$id", - 'itemtype' => 'Ticket', + 'itemtype' => Ticket::class, 'name' => $issueName, 'status' => $validationStatus, 'date_creation' => $item->fields['date'], @@ -581,7 +597,7 @@ function plugin_formcreator_dynamicReport($params) { case PluginFormcreatorFormAnswer::class; if ($url = parse_url($_SERVER['HTTP_REFERER'])) { if (strpos($url['path'], - Toolbox::getItemTypeFormURL("PluginFormcreatorForm")) !== false) { + Toolbox::getItemTypeFormURL(PluginFormcreatorForm::class)) !== false) { parse_str($url['query'], $query); if (isset($query['id'])) { $item = PluginFormcreatorCommon::getForm(); diff --git a/inc/formanswer.class.php b/inc/formanswer.class.php index 80c8baaff..dfd9791f2 100644 --- a/inc/formanswer.class.php +++ b/inc/formanswer.class.php @@ -1418,8 +1418,6 @@ public function createIssue() { 'entities_id' => $this->fields['entities_id'], 'is_recursive' => $this->fields['is_recursive'], 'requester_id' => $this->fields['requester_id'], - 'users_id_validator' => $this->fields['users_id_validator'], - 'groups_id_validator'=> $this->fields['groups_id_validator'], 'comment' => '', ]); @@ -1522,8 +1520,6 @@ private function updateIssue() { 'entities_id' => $this->fields['entities_id'], 'is_recursive' => $this->fields['is_recursive'], 'requester_id' => $this->fields['requester_id'], - 'users_id_validator' => $this->fields['users_id_validator'], - 'groups_id_validator'=> $this->fields['groups_id_validator'], 'comment' => '', ]); diff --git a/inc/issue.class.php b/inc/issue.class.php index 28d6dfeec..040beefde 100644 --- a/inc/issue.class.php +++ b/inc/issue.class.php @@ -105,8 +105,6 @@ public static function getSyncIssuesRequest() : AbstractQuery { 'entities_id as entities_d', 'is_recursive as is_recursive', 'requester_id as requester_id', - 'users_id_validator as users_id_validator', - 'groups_id_validator as groups_id_validator', 'comment as comment', 'requester_id as users_id_recipient' ], @@ -145,16 +143,13 @@ public static function getSyncIssuesRequest() : AbstractQuery { new QueryExpression("CONCAT('t_', `$ticketTable`.`id`) as `display_id`"), "$ticketTable.id as items_id", new QueryExpression("'" . Ticket::getType() . "' as `itemtype`"), - new QueryExpression("IF(`$ticketValidationTable`.`status` IS NULL, + new QueryExpression("IF(`$ticketTable`.`global_validation` IN ('" . CommonITILValidation::NONE . "', '" . CommonITILValidation::ACCEPTED . "'), `$ticketTable`.`status`, - IF(`$ticketTable`.`global_validation` IN ('" . CommonITILValidation::NONE . "', '" . CommonITILValidation::ACCEPTED . "'), + IF(`$ticketTable`.`status` IN ('" . CommonITILObject::SOLVED . "', '" . CommonITILObject::CLOSED . "'), `$ticketTable`.`status`, - IF(`$ticketTable`.`status` IN ('" . CommonITILObject::SOLVED . "', '" . CommonITILObject::CLOSED . "'), - `$ticketTable`.`status`, - IF(`$ticketTable`.`global_validation` = '" . CommonITILValidation::WAITING . "', - '" . PluginFormcreatorFormAnswer::STATUS_WAITING . "', - '" . PluginFormcreatorFormAnswer::STATUS_REFUSED . "' - ) + IF(`$ticketTable`.`global_validation` = '" . CommonITILValidation::WAITING . "', + '" . PluginFormcreatorFormAnswer::STATUS_WAITING . "', + '" . PluginFormcreatorFormAnswer::STATUS_REFUSED . "' ) ) ) AS `status`"), @@ -165,8 +160,6 @@ public static function getSyncIssuesRequest() : AbstractQuery { ], new QueryExpression('0 as is_recursive'), new QueryExpression("COALESCE(`$ticketUserTable`.`users_id`, 0) as `requester_id`"), - new QueryExpression("COALESCE(`$ticketValidationTable`.`users_id_validate`, 0) as `users_id_validator`"), - new QueryExpression('0 as groups_id_validator'), "$ticketTable.content as comment", 'users_id_recipient as users_id_recipient' ], @@ -198,12 +191,6 @@ public static function getSyncIssuesRequest() : AbstractQuery { $ticketUserTable => $ticketFk, ], ], - $ticketValidationTable => [ - 'FKEY' => [ - $ticketTable => 'id', - $ticketValidationTable => $ticketFk, - ], - ], ], 'WHERE' => [ "$ticketTable.is_deleted" => 0, @@ -219,7 +206,7 @@ public static function getSyncIssuesRequest() : AbstractQuery { 'INNER JOIN' => [$itemTicketTable => $query2['LEFT JOIN'][$itemTicketTable]], 'LEFT JOIN' => [ $query2['LEFT JOIN'][0], // This is the TABLE => [...] subquery - $ticketValidationTable => $query2['LEFT JOIN'][$ticketValidationTable], + // $ticketValidationTable => $query2['LEFT JOIN'][$ticketValidationTable], ], 'WHERE' => $query2['WHERE'], 'GROUPBY' => ["$itemTicketTable.items_id"], @@ -521,7 +508,6 @@ public function rawSearchOptions() { 'name' => __('Name'), 'datatype' => 'itemlink', 'massiveaction' => false, - 'forcegroupby' => true, 'additionalfields' => [ '0' => 'display_id' ] @@ -608,14 +594,22 @@ public function rawSearchOptions() { } else { $newtab = [ 'id' => '9', - 'table' => 'glpi_users', + 'table' => User::getTable(), 'field' => 'name', 'linkfield' => 'users_id_validator', 'name' => __('Form approver', 'formcreator'), 'datatype' => 'dropdown', - 'massiveaction' => false + 'massiveaction' => false, + 'joinparams' => [ + 'beforejoin' => [ + 'table' => PluginFormcreatorFormAnswer::getTable(), + 'joinparams' => [ + 'jointype' => 'itemtype_item_revert', + 'specific_itemtype' => PluginFormcreatorFormAnswer::class, + ] + ], + ], ]; - } if (!Session::isCron() // no filter for cron && Session::getCurrentInterface() == 'helpdesk') { @@ -640,12 +634,12 @@ public function rawSearchOptions() { 'field' => 'name', 'linkfield' => 'users_id_validate', 'name' => __('Ticket approver', 'formcreator'), - 'datatype' => 'dropdown', + 'datatype' => 'itemlink', 'right' => [ '0' => 'validate_request', '1' => 'validate_incident' ], - 'forcegroupby' => false, + 'forcegroupby' => true, 'massiveaction' => false, 'joinparams' => [ 'beforejoin' => [ @@ -663,6 +657,12 @@ public function rawSearchOptions() { ], ] ]; + if (version_compare(GLPI_VERSION, '10.1') >= 0) { + $newtab['linkfield'] = 'items_id_target'; + $newtab['condition'] = [ + 'REFTABLE.itemtype_target' => User::class, + ]; + } if (!Session::isCron() // no filter for cron && Session::getCurrentInterface() == 'helpdesk') { $newtab['right'] = 'id'; @@ -675,7 +675,6 @@ public function rawSearchOptions() { 'field' => 'name', 'name' => __('Technician'), 'datatype' => 'dropdown', - 'forcegroupby' => true, 'massiveaction' => false, 'nodisplay' => $hide_technician, 'nosearch' => $hide_technician, @@ -716,7 +715,9 @@ public function rawSearchOptions() { 'beforejoin' => [ 'table' => Group_Ticket::getTable(), 'joinparams' => [ - 'condition' => "AND NEWTABLE.`type` = '2'", // Assign + 'condition' => [ + 'NEWTABLE.type' => CommonITILActor::ASSIGN, + ], 'jointype' => 'child', 'beforejoin' => [ 'table' => Ticket::getTable(), @@ -732,17 +733,63 @@ public function rawSearchOptions() { } if (Plugin::isPluginActive(PLUGIN_FORMCREATOR_ADVANCED_VALIDATION)) { - $tab[] = PluginAdvformIssue::rawSearchOptionFormApproverGroup(); + $newtab = PluginAdvformIssue::rawSearchOptionFormApproverGroup(); } else { - $tab[] = [ + $newtab = [ 'id' => '16', - 'table' => 'glpi_groups', + 'table' => Group::getTable(), 'field' => 'completename', + 'linkfield' => 'groups_id_validator', 'name' => __('Form approver group', 'formcreator'), 'datatype' => 'itemlink', 'massiveaction' => false, - 'linkfield' => 'groups_id_validator', + 'joinparams' => [ + 'beforejoin' => [ + 'table' => PluginFormcreatorFormAnswer::getTable(), + 'joinparams' => [ + 'jointype' => 'itemtype_item_revert', + 'specific_itemtype' => PluginFormcreatorFormAnswer::class, + ] + ], + ], + ]; + } + $tab[] = $newtab; + + if (version_compare(GLPI_VERSION, '10.1') >= 0) { + $newtab = [ + 'id' => '17', + 'table' => Group::getTable(), + 'field' => 'name', + 'linkfield' => 'items_id_target', + 'name' => __('Ticket approver group', 'formcreator'), + 'datatype' => 'itemlink', + 'condition' => [ + 'REFTABLE.itemtype_target' => User::class, + ], + 'right' => [ + '0' => 'validate_request', + '1' => 'validate_incident' + ], + 'forcegroupby' => true, + 'massiveaction' => false, + 'joinparams' => [ + 'beforejoin' => [ + 'table' => TicketValidation::getTable(), + 'joinparams' => [ + 'jointype' => 'child', + 'beforejoin' => [ + 'table' => Ticket::getTable(), + 'joinparams' => [ + 'jointype' => 'itemtype_item_revert', + 'specific_itemtype' => Ticket::class, + ] + ] + ] + ], + ] ]; + $tab[] = $newtab; } if (Plugin::isPluginActive(PLUGIN_FORMCREATOR_ADVANCED_VALIDATION)) { diff --git a/install/install.php b/install/install.php index 10fa0c6e0..1eb315b08 100644 --- a/install/install.php +++ b/install/install.php @@ -78,6 +78,7 @@ class PluginFormcreatorInstall { '2.12.1' => '2.12.5', '2.12.5' => '2.13', '2.13' => '2.13.1', + '2.13.1' => '2.13.3', ]; protected bool $resyncIssues = false; diff --git a/install/mysql/plugin_formcreator_2.13.3_empty.sql b/install/mysql/plugin_formcreator_2.13.3_empty.sql index a83d74bb6..90570138d 100644 --- a/install/mysql/plugin_formcreator_2.13.3_empty.sql +++ b/install/mysql/plugin_formcreator_2.13.3_empty.sql @@ -294,16 +294,12 @@ CREATE TABLE IF NOT EXISTS `glpi_plugin_formcreator_issues` ( `entities_id` int unsigned NOT NULL DEFAULT '0', `is_recursive` tinyint(1) NOT NULL DEFAULT '0', `requester_id` int unsigned NOT NULL DEFAULT '0', - `users_id_validator` int unsigned NOT NULL DEFAULT '0', - `groups_id_validator` int unsigned NOT NULL DEFAULT '0', `comment` longtext, `users_id_recipient` int unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`id`), INDEX `item` (`itemtype`, `items_id`), INDEX `entities_id` (`entities_id`), - INDEX `requester_id` (`requester_id`), - INDEX `users_id_validator` (`users_id_validator`), - INDEX `groups_id_validator` (`groups_id_validator`) + INDEX `requester_id` (`requester_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC; CREATE TABLE IF NOT EXISTS `glpi_plugin_formcreator_items_targettickets` ( `id` int unsigned NOT NULL AUTO_INCREMENT, diff --git a/install/upgrade_to_2.13.3.php b/install/upgrade_to_2.13.3.php new file mode 100644 index 000000000..d29a0ea3d --- /dev/null +++ b/install/upgrade_to_2.13.3.php @@ -0,0 +1,54 @@ +. + * --------------------------------------------------------------------- + * @copyright Copyright © 2011 - 2021 Teclib' + * @license http://www.gnu.org/licenses/gpl.txt GPLv3+ + * @link https://github.com/pluginsGLPI/formcreator/ + * @link https://pluginsglpi.github.io/formcreator/ + * @link http://plugins.glpi-project.org/#/plugin/formcreator + * --------------------------------------------------------------------- + */ +class PluginFormcreatorUpgradeTo2_13_3 { + /** @var Migration */ + protected $migration; + + public function isResyncIssuesRequired() { + return true; + } + + /** + * @param Migration $migration + */ + public function upgrade(Migration $migration) { + $this->migration = $migration; + $this->dropIssuesValidators(); + } + + public function dropIssuesValidators() { + $table = 'glpi_plugin_formcreator_issues'; + $this->migration->dropKey($table, 'users_id_validator'); + $this->migration->dropKey($table, 'groups_id_validator'); + $this->migration->dropField($table, 'users_id_validator'); + $this->migration->dropField($table, 'groups_id_validator'); + } +} diff --git a/tests/3-unit/PluginFormcreatorIssue.php b/tests/3-unit/PluginFormcreatorIssue.php index 9b5ad7772..1e8f9c3bb 100644 --- a/tests/3-unit/PluginFormcreatorIssue.php +++ b/tests/3-unit/PluginFormcreatorIssue.php @@ -32,6 +32,12 @@ namespace tests\units; use GlpiPlugin\Formcreator\Tests\CommonTestCase; use Ticket; +use PluginFormcreatorFormAnswer; +use RuleAction; +use User; +use Rule; +use RuleCriteria; +use CommonITILObject; class PluginFormcreatorIssue extends CommonTestCase { public function beforeTestMethod($method) { @@ -109,8 +115,6 @@ public function providerGetsyncIssuesRequest_simpleTicket() { 'requester_id' => $ticket2->fields['users_id_recipient'], 'date_creation' => $ticket2->fields['date'], 'date_mod' => $ticket2->fields['date_mod'], - 'users_id_validator' => '0', - 'groups_id_validator' => '0', ] ] ]; @@ -145,6 +149,7 @@ public function providerGetsyncIssuesRequest_simpleFormanswers() { } public function providerGetSyncIssuesRequest_formAnswerWithOneTicket() { + // case 1 $form = $this->getForm(); $targetTicket1 = new \PluginFormcreatorTargetTicket(); $targetTicket1->add([ @@ -162,6 +167,46 @@ public function providerGetSyncIssuesRequest_formAnswerWithOneTicket() { $ticket = array_shift($formAnswer->targetList); $this->object($ticket)->isInstanceOf(\Ticket::getType()); + // case 2 + // Add business rules to add 2 validators + $rule = $this->getGlpiCoreItem(Rule::class, [ + 'sub_type' => RuleTicket::class, + 'name' => 'add validators', + 'match' => 'AND', + 'is_active' => 1, + 'condition' => 1, + ]); + $ruleCriteria = $this->getGlpiCoreItem(RuleCriteria::class, [ + $rule::getForeignKeyField() => $rule->getID(), + 'criteria' => '_groups_id_of_requester', + 'condition' => 1, + 'pattern' => User::getIdByName('normal'), + ]); + $ruleAction = $this->getGlpiCoreItem(RuleAction::class, [ + $rule::getForeignKeyField() => $rule->getID(), + 'action_type' => 'add_validation', + 'field' => 'users_id_validate', + 'value' => User::getIdByName('glpi'), + ]); + $ruleAction = $this->getGlpiCoreItem(RuleAction::class, [ + $rule::getForeignKeyField() => $rule->getID(), + 'action_type' => 'add_validation', + 'field' => 'users_id_validate', + 'value' => User::getIdByName('normal'), + ]); + $formAnswer = new \PluginFormcreatorFormAnswer(); + $formAnswer->add([ + 'plugin_formcreator_forms_id' => $form->getID(), + ]); + $rule->update([ + 'id' => $rule->getID(), + 'is_active' => 0, + ]); + $this->boolean($formAnswer->isNewItem())->isFalse(); + $formAnswer->getFromDB($formAnswer->getID()); + $ticket2 = array_shift($formAnswer->targetList); + $this->object($ticket)->isInstanceOf(\Ticket::getType()); + return [ 'formAnswerWithOneTicket' => [ 'item' => $ticket, @@ -176,6 +221,19 @@ public function providerGetSyncIssuesRequest_formAnswerWithOneTicket() { 'date_mod' => $ticket->fields['date_mod'], ], ], + 'formAnswer With One Ticket Having several validators' => [ + 'item' => $ticket2, + 'expected' => [ + 'itemtype' => \Ticket::getType(), + 'items_id' => $ticket2->getID(), + 'display_id' => 't_' . $ticket2->getID(), + 'name' => $ticket2->fields['name'], + 'status' => CommonITILObject::ASSIGNED, + 'requester_id' => $ticket2->fields['users_id_recipient'], + 'date_creation' => $ticket2->fields['date'], + 'date_mod' => $ticket2->fields['date_mod'], + ], + ], ]; } @@ -279,8 +337,6 @@ public function providerGetSyncIssuesRequest_formanswerUnderValidation() { 'requester_id' => $formAnswer->fields['requester_id'], 'date_creation' => $formAnswer->fields['request_date'], 'date_mod' => $formAnswer->fields['request_date'], - //'users_id_validator' => '4', // Tech - //'groups_id_validator' => '0', ], ], ]; @@ -319,8 +375,6 @@ public function providerGetsyncIssuesRequest_ticketUnderValidation() { 'requester_id' => $ticket->fields['users_id_recipient'], 'date_creation' => $ticket->fields['date'], 'date_mod' => $ticket->fields['date_mod'], - // 'users_id_validator' => '4', // Tech - // 'groups_id_validator' => '0', ], ], ]; @@ -358,6 +412,26 @@ public function providerGetsyncIssuesRequest_validatedTicket() { 'status' => \TicketValidation::ACCEPTED ]); + $ticket2 = $this->getGlpiCoreItem(Ticket::class, [ + 'name' => 'a ticket', + 'content' => 'foo', + 'status' => \Ticket::INCOMING, + '_add_validation' => '0', + 'validatortype' => User::class, + 'users_id_validate' => [User::getIdByName('tech'), User::getIdByName('normal')], // Tech + '_actors' => [ + 'requester' => [ + 0 => ['itemtype' => \User::class, + 'items_id' => User::getIdByName('glpi'), // glpi + 'use_notification' => 1, + 'alternative_email' => '', + ] + ] + ] + ]); + $this->boolean($ticket2->isNewItem())->isFalse(); + $ticket2->getFromDB($ticket2->getID()); + return [ 'validatedTicket' => [ 'item' => $ticket, @@ -370,10 +444,21 @@ public function providerGetsyncIssuesRequest_validatedTicket() { 'requester_id' => $ticket->fields['users_id_recipient'], 'date_creation' => $ticket->fields['date'], 'date_mod' => $ticket->fields['date_mod'], - // 'users_id_validator' => '4', // Tech - // 'groups_id_validator' => '0', ], ], + 'ticket with multiple validators' => [ + 'item' => $ticket2, + 'expected' => [ + 'itemtype' => \Ticket::getType(), + 'items_id' => $ticket2->getID(), + 'display_id' => 't_' . $ticket2->getID(), + 'name' => $ticket2->fields['name'], + 'status' => PluginFormcreatorFormAnswer::STATUS_WAITING, + 'requester_id' => $ticket2->fields['users_id_recipient'], + 'date_creation' => $ticket2->fields['date'], + 'date_mod' => $ticket2->fields['date_mod'], + ], + ] ]; }