diff --git a/front/targetproblem.form.php b/front/targetproblem.form.php new file mode 100644 index 000000000..18ffb6ed8 --- /dev/null +++ b/front/targetproblem.form.php @@ -0,0 +1,95 @@ +. + * --------------------------------------------------------------------- + * @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 + * --------------------------------------------------------------------- + */ + +include ('../../../inc/includes.php'); + +Session::checkRight('entity', UPDATE); + +// Check if plugin is activated... +if (!(new Plugin())->isActivated('formcreator')) { + Html::displayNotFoundError(); +} +$targetProblem = new PluginFormcreatorTargetProblem(); + +// Edit an existing target problem +if (isset($_POST['update'])) { + $targetProblem->update($_POST); + Html::back(); + +} else if (isset($_POST['actor_role'])) { + $id = (int) $_POST['id']; + $actor_value = isset($_POST['actor_value_' . $_POST['actor_type']]) + ? $_POST['actor_value_' . $_POST['actor_type']] + : ''; + $use_notification = ($_POST['use_notification'] == 0) ? 0 : 1; + $targetProblem_actor = new PluginFormcreatorTarget_Actor(); + $targetProblem_actor->add([ + 'itemtype' => $targetProblem->getType(), + 'items_id' => $id, + 'actor_role' => $_POST['actor_role'], + 'actor_type' => $_POST['actor_type'], + 'actor_value' => $actor_value, + 'use_notification' => $use_notification, + ]); + Html::back(); + +} else if (isset($_GET['delete_actor'])) { + $targetProblem_actor = new PluginFormcreatorTarget_Actor(); + $targetProblem_actor->delete([ + 'itemtype' => $targetProblem->getType(), + 'items_id' => $id, + 'id' => (int) $_GET['delete_actor'] + ]); + Html::back(); + + // Show target ticket form +} else { + Html::header( + __('Form Creator', 'formcreator'), + $_SERVER['PHP_SELF'], + 'admin', + 'PluginFormcreatorForm' + ); + + $itemtype = PluginFormcreatorTargetProblem::class; + $targetProblem->getFromDB((int) $_REQUEST['id']); + $form = $targetProblem->getForm(); + + $_SESSION['glpilisttitle'][$itemtype] = sprintf( + __('%1$s = %2$s'), + $form->getTypeName(1), $form->getName() + ); + $_SESSION['glpilisturl'][$itemtype] = $form->getFormURL()."?id=".$form->getID(); + + $targetProblem->display($_REQUEST); + + Html::footer(); +} diff --git a/inc/abstracttarget.class.php b/inc/abstracttarget.class.php index 1309b7355..53fd179e5 100644 --- a/inc/abstracttarget.class.php +++ b/inc/abstracttarget.class.php @@ -2473,4 +2473,30 @@ public function getDefaultData(PluginFormcreatorFormAnswer $formanswer): array { $data = array_merge($data, $predefined_fields); return $data; } + + /** + * get all target problems for a form + * + * @param int $formId + * @return array + */ + public function getTargetsForForm($formId) { + global $DB; + + $targets = []; + $rows = $DB->request([ + 'SELECT' => ['id'], + 'FROM' => static::getTable(), + 'WHERE' => [ + 'plugin_formcreator_forms_id' => $formId + ], + ]); + foreach ($rows as $row) { + $target = new static(); + $target->getFromDB($row['id']); + $targets[$row['id']] = $target; + } + + return $targets; + } } diff --git a/inc/form.class.php b/inc/form.class.php index 6cbe9ca06..87069404f 100644 --- a/inc/form.class.php +++ b/inc/form.class.php @@ -2238,7 +2238,8 @@ public function getFields() : array { public static function getTargetTypes() : array { return [ PluginFormcreatorTargetTicket::class, - PluginFormcreatorTargetChange::class + PluginFormcreatorTargetChange::class, + PluginFormcreatorTargetProblem::class, ]; } diff --git a/inc/targetchange.class.php b/inc/targetchange.class.php index 8009bf610..086d25fd1 100644 --- a/inc/targetchange.class.php +++ b/inc/targetchange.class.php @@ -415,7 +415,6 @@ public function showForm($ID, $options = []) { $title = __('Edit a target', 'formcreator'); } - // TODO: remive the fixed width echo '
' . $title . ''; echo ''; echo '' . __('Name') . ' *'; - // TODO: remive the fixed width echo ''; echo Html::input('name', [ 'id' => 'name', @@ -901,30 +899,4 @@ public function save(PluginFormcreatorFormAnswer $formanswer) { return $change; } - - /** - * get all target changes for a form - * - * @param int $formId - * @return array - */ - public function getTargetsForForm($formId) { - global $DB; - - $targets = []; - $rows = $DB->request([ - 'SELECT' => ['id'], - 'FROM' => self::getTable(), - 'WHERE' => [ - 'plugin_formcreator_forms_id' => $formId - ], - ]); - foreach ($rows as $row) { - $target = new self(); - $target->getFromDB($row['id']); - $targets[$row['id']] = $target; - } - - return $targets; - } } diff --git a/inc/targetproblem.class.php b/inc/targetproblem.class.php new file mode 100644 index 000000000..84ff98851 --- /dev/null +++ b/inc/targetproblem.class.php @@ -0,0 +1,737 @@ +. + * --------------------------------------------------------------------- + * @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 + * --------------------------------------------------------------------- + */ + +use GlpiPlugin\Formcreator\Exception\ImportFailureException; +use GlpiPlugin\Formcreator\Exception\ExportFailureException; + +if (!defined('GLPI_ROOT')) { + die("Sorry. You can't access this file directly"); +} + +class PluginFormcreatorTargetProblem extends PluginFormcreatorAbstractTarget { + public static function getTypeName($nb = 1) { + return _n('Target problem', 'Target problems', $nb, 'formcreator'); + } + + protected function getItem_User() { + return new Problem_User(); + } + + protected function getItem_Group() { + return new Group_Problem(); + } + + protected function getItem_Supplier() { + return new Problem_Supplier(); + } + + protected function getItem_Item() { + return new Item_Problem(); + } + + protected function getTargetItemtypeName(): string { + return Problem::class; + } + + protected function getTemplateItemtypeName(): string { + return ProblemTemplate::class; + } + + protected function getTemplatePredefinedFieldItemtype(): string { + return ProblemTemplatePredefinedField::class; + } + protected function getCategoryFilter() { + return [ + 'is_problem' => 1, + ]; + } + + /** + * Show the Form for the adminsitrator to edit in the config page + * + * @param array $options Optional options + * @return void + */ + public function showForm($ID, $options = []) { + if ($ID == 0) { + // Not used for now + $title = __('Add a target ', 'formcreator'); + } else { + $title = __('Edit a target', 'formcreator'); + } + $rand = mt_rand(); + + $form = $this->getForm(); + + echo ''; + + // General information: target_name + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo '
' . $title . '
' . __('Name') . ' *'; + echo Html::input('name', [ + 'id' => 'name', + 'autofocus' => '', + 'value' => $this->fields['name'], + ]); + echo '
'; + + // Ticket information: title, template... + echo ''; + + echo ''; + + echo ''; + echo ''; + echo ''; + echo ''; + + echo ''; + echo ''; + echo ''; + echo ''; + + echo ''; + echo ''; + echo ''; + echo ''; + + echo ''; + echo ''; + echo ''; + echo ''; + + echo ''; + echo ''; + echo ''; + echo ''; + + $rand = mt_rand(); + $this->showDestinationEntitySetings($rand); + + echo ''; + $this->showTemplateSettings($rand); + echo ''; + + // ------------------------------------------------------------------------------------------- + // category of the target + // ------------------------------------------------------------------------------------------- + $this->showCategorySettings($rand); + + // ------------------------------------------------------------------------------------------- + // Urgency selection + // ------------------------------------------------------------------------------------------- + $this->showUrgencySettings($rand); + + // ------------------------------------------------------------------------------------------- + // Tags + // ------------------------------------------------------------------------------------------- + $this->showPluginTagsSettings($rand); + + // ------------------------------------------------------------------------------------------- + // Validation as ticket followup + // ------------------------------------------------------------------------------------------- + if ($form->fields['validation_required']) { + echo ''; + echo ''; + echo ''; + } + + // ------------------------------------------------------------------------------------------- + // Conditions to generate the target + // ------------------------------------------------------------------------------------------- + echo ''; + echo ''; + echo ''; + $this->showConditionsSettings($rand); + + echo '
' . $this->getTypeName(1) . '
' . __('Problem title', 'formcreator') . ' *'; + echo Html::input('target_name', [ + 'id' => 'target_name', + 'autofocus' => '', + 'value' => $this->fields['target_name'], + ]); + echo '
' . __('Description') . ' *'; + echo Html::textarea([ + 'name' => 'content', + 'value' => $this->fields['content'], + 'enable_richtext' => true, + 'display' => false, + ]); + echo '
' . __('Impacts') . ' '; + echo Html::textarea([ + 'name' => 'impactcontent', + 'value' => $this->fields['impactcontent'], + 'display' => false, + ]); + echo '
' . __('Cause') . ' '; + echo Html::textarea([ + 'name' => 'causecontent', + 'value' => $this->fields['causecontent'], + 'display' => false, + ]); + echo '
' . __('Symptom') . ' '; + echo Html::textarea([ + 'name' => 'symptomcontent', + 'value' => $this->fields['symptomcontent'], + 'display' => false, + ]); + echo '
'; + echo ''; + echo 'fields['validation_followup']) || ($this->fields['validation_followup'] == 1)) { + echo ' checked="checked"'; + } + echo '/>'; + echo ' '; + echo '
'; + echo __('Condition to create the target', 'formcreator'); + echo ''; + echo '
'; + + // Buttons + echo ''; + + echo ''; + echo ''; + echo ''; + + echo ''; + echo ''; + echo ''; + + echo '
'; + $formFk = PluginFormcreatorForm::getForeignKeyField(); + echo Html::hidden('id', ['value' => $ID]); + echo Html::hidden($formFk, ['value' => $this->fields[$formFk]]); + echo '
'; + echo Html::submit(_x('button', 'Save'), ['name' => 'update']); + echo '
'; + Html::closeForm(); + + $this->showActorsSettings(); + + $this->showTagsList(); + } + + /** + * Save form data to the target + * + * @param PluginFormcreatorFormAnswer $formanswer Answers previously saved + * + * @return Ticket|null Generated ticket if success, null otherwise + */ + public function save(PluginFormcreatorFormAnswer $formanswer) { + $data = []; + $problem = new Problem(); + $form = $formanswer->getForm(); + $data = $this->getDefaultData($formanswer); + + // Parse data + $domain = PluginFormcreatorForm::getTranslationDomain($form->getID()); + $data['name'] = $this->prepareTemplate( + __($this->fields['target_name'], $domain), + $formanswer, + true + ); + $data['name'] = Toolbox::addslashes_deep($data['name']); + $data['name'] = $formanswer->parseTags($data['name'], $this); + + $problemFields = [ + 'content', + 'impactcontent', + 'causecontent', + 'symptomcontent', + ]; + foreach ($problemFields as $problemFields) { + $data[$problemFields] = $this->prepareTemplate( + $this->fields[$problemFields], + $formanswer, + $problemFields == 'content' // only content supports rich text + ); + $data[$problemFields] = $data[$problemFields] ?? ''; + + $data[$problemFields] = $formanswer->parseTags($data[$problemFields], $this, $problemFields == 'content'); + } + + $data['_users_id_recipient'] = $_SESSION['glpiID']; + + $this->prepareActors($form, $formanswer); + + if (count($this->requesters['_users_id_requester']) == 0) { + $this->addActor('requester', $formanswer->fields['requester_id'], true); + $requesters_id = $formanswer->fields['requester_id']; + } else { + $requesterAccounts = array_filter($this->requesters['_users_id_requester'], function($v) { + return ($v != 0); + }); + $requesters_id = array_shift($requesterAccounts); + if ($requesters_id === null) { + // No account for requesters, then fallback on the account used to fill the answers + $requesters_id = $formanswer->fields['requester_id']; + } + } + + $data = $this->setTargetEntity($data, $formanswer, $requesters_id); + $data = $this->setTargetUrgency($data, $formanswer); + + $data = $this->requesters + $this->observers + $this->assigned + $this->assignedSuppliers + $data; + $data = $this->requesterGroups + $this->observerGroups + $this->assignedGroups + $data; + + // Create the target problem + if (!$problemID = $problem->add($data)) { + return null; + } + + $this->saveTags($formanswer, $problemID); + + // Add link between Problem and FormAnswer + $itemlink = $this->getItem_Item(); + $itemlink->add([ + 'itemtype' => PluginFormcreatorFormAnswer::class, + 'items_id' => $formanswer->fields['id'], + 'problems_id' => $problemID, + ]); + + $this->attachDocument($formanswer->getID(), Problem::class, $problem); + + return $problem; + } + + protected function getTaggableFields() { + return [ + 'target_name', + 'content', + 'impactcontent', + 'causecontent', + 'symptomcontent', + ]; + } + + public function prepareInputForUpdate($input) { + // Control fields values : + if (!isset($input['_skip_checks']) + || !$input['_skip_checks']) { + + $input['content'] = Html::entity_decode_deep($input['content']); + + if (isset($input['destination_entity'])) { + switch ($input['destination_entity']) { + case self::DESTINATION_ENTITY_SPECIFIC : + $input['destination_entity_value'] = $input['_destination_entity_value_specific']; + unset($input['_destination_entity_value_specific']); + break; + case self::DESTINATION_ENTITY_USER : + $input['destination_entity_value'] = $input['_destination_entity_value_user']; + unset($input['_destination_entity_value_user']); + break; + case self::DESTINATION_ENTITY_ENTITY : + $input['destination_entity_value'] = $input['_destination_entity_value_entity']; + unset($input['_destination_entity_value_entity']); + break; + default : + $input['destination_entity_value'] = 'NULL'; + break; + } + } + + if (isset($input['urgency_rule'])) { + switch ($input['urgency_rule']) { + case self::URGENCY_RULE_ANSWER: + $input['urgency_question'] = $input['_urgency_question']; + unset($input['_urgency_question']); + break; + case self::URGENCY_RULE_SPECIFIC: + $input['urgency_question'] = $input['_urgency_specific']; + unset($input['_urgency_specific']); + break; + default: + $input['urgency_question'] = '0'; + } + } + + if (isset($input['category_rule'])) { + switch ($input['category_rule']) { + case self::CATEGORY_RULE_ANSWER: + $input['category_question'] = $input['_category_question']; + unset($input['_category_question']); + break; + case self::CATEGORY_RULE_SPECIFIC: + $input['category_question'] = $input['_category_specific']; + unset($input['_category_specific']); + break; + default: + $input['category_question'] = '0'; + } + } + + $plugin = new Plugin(); + if ($plugin->isInstalled('tag') && $plugin->isActivated('tag')) { + $input['tag_questions'] = (!empty($input['_tag_questions'])) + ? implode(',', $input['_tag_questions']) + : ''; + $input['tag_specifics'] = (!empty($input['_tag_specifics'])) + ? implode(',', $input['_tag_specifics']) + : ''; + } + } + + return parent::prepareInputForUpdate($input); + } + + /** + * Hook for pre_purge of the item. + * GLPI does not provides pre_purgeItem, this is emulated with + * the hook pre_purge_item + * + * @param CommonDBTM $item + * @return boolean + */ + public function pre_purgeItem() { + if (!parent::pre_purgeItem()) { + $this->input = false; + return false; + } + + // delete conditions + if (! (new PluginFormcreatorCondition())->deleteByCriteria([ + 'itemtype' => self::class, + 'items_id' => $this->getID(), + ])) { + return false; + } + + return true; + } + + public function post_addItem() { + parent::post_addItem(); + if (!isset($this->input['_skip_checks']) || !$this->input['_skip_checks']) { + $this->updateConditions($this->input); + } + } + + public function post_updateItem($history = 1) { + parent::post_updateItem(); + if (!isset($this->input['_skip_checks']) || !$this->input['_skip_checks']) { + $this->updateConditions($this->input); + } + } + + protected function getTargetTemplate(array $data): int { + global $DB; + + $targetItemtype = $this->getTemplateItemtypeName(); + $targetTemplateFk = $targetItemtype::getForeignKeyField(); + if ($targetItemtype::isNewID($this->fields[$targetTemplateFk]) && !ITILCategory::isNewID($data['itilcategories_id'])) { + $rows = $DB->request([ + 'SELECT' => [$targetTemplateFk], + 'FROM' => ITILCategory::getTable(), + 'WHERE' => ['id' => $data['itilcategories_id']] + ]); + if ($row = $rows->next()) { + // assign problem template according to resulting problem category + return $row[$targetTemplateFk]; + } + } + + return $this->fields[$targetTemplateFk] ?? 0; + } + + /** + * Export in an array all the data of the current instanciated targetticket + * @return array the array with all data (with sub tables) + */ + public function export(bool $remove_uuid = false): array { + if ($this->isNewItem()) { + throw new ExportFailureException(sprintf(__('Cannot export an empty object: %s', 'formcreator'), $this->getTypeName())); + } + + $export = $this->fields; + + // remove key and fk + $formFk = PluginFormcreatorForm::getForeignKeyField(); + unset($export[$formFk]); + + // replace dropdown ids + $export['_problemtemplate'] = ''; + if ($export['problemtemplates_id'] > 0) { + $export['_problemtemplate'] + = Dropdown::getDropdownName('glpi_problemtemplates', + $export['problemtemplates_id']); + } + unset($export['problemtemplates_id']); + + $subItems = [ + '_actors' => PluginFormcreatorTarget_Actor::class, + '_conditions' => PluginFormcreatorCondition::class, + ]; + $export = $this->exportChildrenObjects($subItems, $export, $remove_uuid); + + // remove ID or UUID + $idToRemove = 'id'; + if ($remove_uuid) { + $idToRemove = 'uuid'; + } else { + // Convert IDs into UUIDs + $export = $this->convertTags($export); + $questionLinks = [ + 'urgency_rule' => ['values' => self::URGENCY_RULE_ANSWER, 'field' => 'urgency_question'], + 'tag_type' => ['values' => self::TAG_TYPE_QUESTIONS, 'field' => 'tag_questions'], + 'category_rule' => ['values' => self::CATEGORY_RULE_ANSWER, 'field' => 'category_question'], + 'destination_entity' => [ + 'values' => [ + self::DESTINATION_ENTITY_ENTITY, + self::DESTINATION_ENTITY_USER, + ], + 'field' => 'destination_entity_value', + ], + ]; + foreach ($questionLinks as $field => $fieldSetting) { + if (!is_array($fieldSetting['values'])) { + $fieldSetting['values'] = [$fieldSetting['values']]; + } + if (!in_array($export[$field], $fieldSetting['values'])) { + continue; + } + $question = new PluginFormcreatorQuestion(); + $question->getFromDB($export[$fieldSetting['field']]); + $export[$fieldSetting['field']] = $question->fields['uuid']; + } + } + unset($export[$idToRemove]); + + return $export; + } + + public static function import(PluginFormcreatorLinker $linker, array $input = [], int $containerId = 0) { + global $DB; + + if (!isset($input['uuid']) && !isset($input['id'])) { + throw new ImportFailureException(sprintf('UUID or ID is mandatory for %1$s', static::getTypeName(1))); + } + + $formFk = PluginFormcreatorForm::getForeignKeyField(); + $input[$formFk] = $containerId; + $input['_skip_checks'] = true; + $input['_skip_create_actors'] = true; + + $item = new self(); + // Find an existing target to update, only if an UUID is available + $itemId = false; + /** @var string $idKey key to use as ID (id or uuid) */ + $idKey = 'id'; + if (isset($input['uuid'])) { + $idKey = 'uuid'; + $itemId = plugin_formcreator_getFromDBByField( + $item, + 'uuid', + $input['uuid'] + ); + } + + // set template + $problemTemplateId = 0; + plugin_formcreator_getFromDBByField( + $problemTemplate = new ProblemTemplate(), + 'name', + $input['_problemtemplate'] + ); + if (!$problemTemplate->isNewItem() && $problemTemplate->canViewItem()) { + $problemTemplateId = $problemTemplate->getID(); + } + $input['problemtemplates_id'] = $problemTemplateId; + + // Escape text fields + foreach (['name'] as $key) { + $input[$key] = $DB->escape($input[$key]); + } + + // Assume that all questions are already imported + // convert question uuid into id + $questions = $linker->getObjectsByType(PluginFormcreatorQuestion::class); + if ($questions !== false) { + $taggableFields = $item->getTaggableFields(); + foreach ($questions as $originalId => $question) { + $newId = $question->getID(); + foreach ($taggableFields as $field) { + $content = $input[$field]; + $content = str_replace("##question_$originalId##", "##question_$newId##", $content); + $content = str_replace("##answer_$originalId##", "##answer_$newId##", $content); + $input[$field] = $content; + } + } + + // escape text fields + foreach ($taggableFields as $key) { + $input[$key] = $DB->escape($input[$key]); + } + } + + // Update links to other questions + $questionLinks = [ + 'urgency_rule' => ['values' => self::URGENCY_RULE_ANSWER, 'field' => 'urgency_question'], + 'tag_type' => ['values' => self::TAG_TYPE_QUESTIONS, 'field' => 'tag_questions'], + 'category_rule' => ['values' => self::CATEGORY_RULE_ANSWER, 'field' => 'category_question'], + 'destination_entity' => [ + 'values' => [ + self::DESTINATION_ENTITY_ENTITY, + self::DESTINATION_ENTITY_USER, + ], + 'field' => 'destination_entity_value', + ], + ]; + foreach ($questionLinks as $field => $fieldSetting) { + if (!is_array($fieldSetting['values'])) { + $fieldSetting['values'] = [$fieldSetting['values']]; + } + if (!in_array($input[$field], $fieldSetting['values'])) { + continue; + } + /**@var PluginFormcreatorQuestion $question */ + $question = $linker->getObject($input[$fieldSetting['field']], PluginFormcreatorQuestion::class); + if ($question === false) { + $typeName = strtolower(self::getTypeName()); + throw new ImportFailureException(sprintf(__('Failed to add or update the %1$s %2$s: a question is missing and is used in a parameter of the target', 'formceator'), $typeName, $input['name'])); + } + $input[$fieldSetting['field']] = $question->getID(); + } + + // Add or update + $originalId = $input[$idKey]; + if ($itemId !== false) { + $input['id'] = $itemId; + $item->update($input); + } else { + unset($input['id']); + $itemId = $item->add($input); + } + if ($itemId === false) { + $typeName = strtolower(self::getTypeName()); + throw new ImportFailureException(sprintf(__('Failed to add or update the %1$s %2$s', 'formceator'), $typeName, $input['name'])); + } + + // add the target to the linker + $linker->addObject($originalId, $item); + + $subItems = [ + '_actors' => PluginFormcreatorTarget_Actor::class, + '_conditions' => PluginFormcreatorCondition::class, + ]; + $item->importChildrenObjects($item, $linker, $subItems, $input); + + return $itemId; + } + + public static function countItemsToImport(array $input) : int { + $subItems = [ + '_actors' => PluginFormcreatorTarget_Actor::class, + '_conditions' => PluginFormcreatorCondition::class, + ]; + + return 1 + self::countChildren($subItems, $input); + } + + public function rawSearchOptions() { + $tab = parent::rawSearchOptions(); + + $tab[] = [ + 'id' => '2', + 'table' => $this::getTable(), + 'field' => 'id', + 'name' => __('ID'), + 'searchtype' => 'contains', + 'massiveaction' => false + ]; + + $tab[] = [ + 'id' => '4', + 'table' => $this::getTable(), + 'field' => 'target_name', + 'name' => __('Problem title', 'formcreator'), + 'datatype' => 'string', + 'searchtype' => 'contains', + 'massiveaction' => false + ]; + + $tab[] = [ + 'id' => '5', + 'table' => $this::getTable(), + 'field' => 'content', + 'name' => __('Content', 'formcreator'), + 'datatype' => 'text', + 'searchtype' => 'contains', + 'massiveaction' => false + ]; + + $tab[] = [ + 'id' => '6', + 'table' => $this::getTable(), + 'field' => 'impactcontent', + 'name' => __('Impact', 'formcreator'), + 'datatype' => 'text', + 'searchtype' => 'contains', + 'massiveaction' => false + ]; + + $tab[] = [ + 'id' => '7', + 'table' => $this::getTable(), + 'field' => 'causecontent', + 'name' => __('Cause', 'formcreator'), + 'datatype' => 'text', + 'searchtype' => 'contains', + 'massiveaction' => false + ]; + + $tab[] = [ + 'id' => '8', + 'table' => $this::getTable(), + 'field' => 'symptomcontent', + 'name' => __('Symptom', 'formcreator'), + 'datatype' => 'text', + 'searchtype' => 'contains', + 'massiveaction' => false + ]; + + return $tab; + } +} diff --git a/inc/targetticket.class.php b/inc/targetticket.class.php index 0e9e68b1a..ae889f07e 100644 --- a/inc/targetticket.class.php +++ b/inc/targetticket.class.php @@ -1543,30 +1543,4 @@ private function saveAssociatedItems($input) { unset($input['items_id']); return $input; } - - /** - * get all target tickets for a form - * - * @param int $formId - * @return array - */ - public function getTargetsForForm($formId) { - global $DB; - - $targets = []; - $rows = $DB->request([ - 'SELECT' => ['id'], - 'FROM' => self::getTable(), - 'WHERE' => [ - 'plugin_formcreator_forms_id' => $formId - ], - ]); - foreach ($rows as $row) { - $target = new self(); - $target->getFromDB($row['id']); - $targets[$row['id']] = $target; - } - - return $targets; - } } diff --git a/install/mysql/plugin_formcreator_empty.sql b/install/mysql/plugin_formcreator_empty.sql index e2941e609..fd752d082 100644 --- a/install/mysql/plugin_formcreator_empty.sql +++ b/install/mysql/plugin_formcreator_empty.sql @@ -217,6 +217,31 @@ CREATE TABLE IF NOT EXISTS `glpi_plugin_formcreator_targettickets` ( INDEX `tickettemplates_id` (`tickettemplates_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +CREATE TABLE IF NOT EXISTS `glpi_plugin_formcreator_targetproblems` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL DEFAULT '', + `plugin_formcreator_forms_id` int(11) NOT NULL DEFAULT '0', + `target_name` varchar(255) NOT NULL DEFAULT '', + `problemtemplates_id` int(11) NOT NULL DEFAULT '0', + `content` longtext, + `impactcontent` longtext, + `causecontent` longtext, + `symptomcontent` longtext, + `urgency_rule` int(11) NOT NULL DEFAULT '1', + `urgency_question` int(11) NOT NULL DEFAULT '0', + `destination_entity` int(11) NOT NULL DEFAULT '1', + `destination_entity_value` int(11) DEFAULT NULL, + `tag_type` int(11) NOT NULL DEFAULT '1', + `tag_questions` varchar(255) NOT NULL DEFAULT '', + `tag_specifics` varchar(255) NOT NULL DEFAULT '', + `category_rule` int(11) NOT NULL DEFAULT '1', + `category_question` int(11) NOT NULL DEFAULT '0', + `show_rule` int(11) NOT NULL DEFAULT '1', + `uuid` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + INDEX `problemtemplates_id` (`problemtemplates_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + CREATE TABLE IF NOT EXISTS `glpi_plugin_formcreator_targets_actors` ( `id` int(11) NOT NULL AUTO_INCREMENT, `itemtype` varchar(255) DEFAULT NULL, diff --git a/tests/2-integration/PluginFormcreatorIssue.php b/tests/2-integration/PluginFormcreatorIssue.php index fe9ab7c5e..6c2ebc105 100644 --- a/tests/2-integration/PluginFormcreatorIssue.php +++ b/tests/2-integration/PluginFormcreatorIssue.php @@ -33,8 +33,24 @@ class PluginFormcreatorIssue extends CommonTestCase { + public function beforeTestMethod($method) { + switch ($method) { + case 'testAddTicket': + case 'testUpdateTicket': + $this->login('post-only', 'postonly'); + break; + + case 'testDeleteTicket': + $this->login('glpi', 'glpi'); + break; + } + } + public function testAddTicket() { - $this->login('post-only', 'postonly'); + global $CFG_GLPI; + + $CFG_GLPI['use_notifications'] = '0'; + // Create a form with a target ticket $form = $this->getForm(); $this->getTargetTicket([ @@ -43,7 +59,10 @@ public function testAddTicket() { // answer the form $formAnswer = new \PluginFormcreatorFormAnswer(); - $formAnswer->add([\PluginFormcreatorForm::getForeignKeyField() => $form->getID()]); + $formAnswer->add([ + \PluginFormcreatorForm::getForeignKeyField() => $form->getID() + ]); + // Get the generated ticket $ticket = array_pop($formAnswer->targetList); $this->object($ticket); @@ -63,7 +82,10 @@ public function testAddTicket() { } public function testUpdateTicket() { - $this->login('post-only', 'postonly'); + global $CFG_GLPI; + + $CFG_GLPI['use_notifications'] = '0'; + // Create a form with a target ticket $form = $this->getForm(); $this->getTargetTicket([ @@ -104,7 +126,10 @@ public function testUpdateTicket() { } public function testDeleteTicket() { - $this->login('glpi', 'glpi'); + global $CFG_GLPI; + + $CFG_GLPI['use_notifications'] = '0'; + $form = $this->getForm(); $this->getTargetTicket([ \PluginFormcreatorForm::getForeignKeyField() => $form->getID(), diff --git a/tests/2-integration/PluginFormcreatorTargetChange.php b/tests/2-integration/PluginFormcreatorTargetChange.php index 9f700a4b7..b74887d64 100644 --- a/tests/2-integration/PluginFormcreatorTargetChange.php +++ b/tests/2-integration/PluginFormcreatorTargetChange.php @@ -44,30 +44,30 @@ public function testTargetChangeActors() { // Create a form with a target change $form = $this->getForm(); - $targetChange = new \PluginFormcreatorTargetChange(); - $targetChange->add([ + $instance = new \PluginFormcreatorTargetChange(); + $instance->add([ 'name' => 'a target', 'plugin_formcreator_forms_id' => $form->getID() ]); - $this->boolean($targetChange->isNewItem())->isFalse(); + $this->boolean($instance->isNewItem())->isFalse(); $requesterActor = new \PluginFormcreatorTarget_Actor(); $observerActor = new \PluginFormcreatorTarget_Actor(); - $targetChangeId = $targetChange->getID(); + $instanceId = $instance->getID(); // find the actors created by default $requesterActor->getFromDBByCrit([ 'AND' => [ - 'itemtype' => $targetChange->getType(), - 'items_id' => $targetChangeId, + 'itemtype' => $instance->getType(), + 'items_id' => $instanceId, 'actor_role' => \PluginFormcreatorTarget_Actor::ACTOR_ROLE_REQUESTER, 'actor_type' => \PluginFormcreatorTarget_Actor::ACTOR_TYPE_AUTHOR, ] ]); $observerActor->getFromDBByCrit([ 'AND' => [ - 'itemtype' => $targetChange->getType(), - 'items_id' => $targetChangeId, + 'itemtype' => $instance->getType(), + 'items_id' => $instanceId, 'actor_role' => \PluginFormcreatorTarget_Actor::ACTOR_ROLE_OBSERVER, 'actor_type' => \PluginFormcreatorTarget_Actor::ACTOR_TYPE_VALIDATOR ] diff --git a/tests/2-integration/PluginFormcreatorTargetProblem.php b/tests/2-integration/PluginFormcreatorTargetProblem.php new file mode 100644 index 000000000..e1eec593a --- /dev/null +++ b/tests/2-integration/PluginFormcreatorTargetProblem.php @@ -0,0 +1,84 @@ +. + * --------------------------------------------------------------------- + * @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 + * --------------------------------------------------------------------- + */ + +namespace tests\units; +use GlpiPlugin\Formcreator\Tests\CommonTestCase; + +class PluginFormcreatorTargetProblem extends CommonTestCase { + + public function beforeTestMethod($method) { + parent::beforeTestMethod($method); + + $this->login('glpi', 'glpi'); + } + + public function testTargetProblemActors() { + // Create a form with a target problem + $form = $this->getForm(); + + $instance = new \PluginFormcreatorTargetProblem(); + $instance->add([ + 'name' => 'a target', + 'plugin_formcreator_forms_id' => $form->getID() + ]); + $this->boolean($instance->isNewItem())->isFalse(); + + $requesterActor = new \PluginFormcreatorTarget_Actor(); + $observerActor = new \PluginFormcreatorTarget_Actor(); + $instanceId = $instance->getID(); + + // find the actors created by default + $requesterActor->getFromDBByCrit([ + 'AND' => [ + 'itemtype' => $instance->getType(), + 'items_id' => $instanceId, + 'actor_role' => \PluginFormcreatorTarget_Actor::ACTOR_ROLE_REQUESTER, + 'actor_type' => \PluginFormcreatorTarget_Actor::ACTOR_TYPE_AUTHOR, + ] + ]); + $observerActor->getFromDBByCrit([ + 'AND' => [ + 'itemtype' => $instance->getType(), + 'items_id' => $instanceId, + 'actor_role' => \PluginFormcreatorTarget_Actor::ACTOR_ROLE_OBSERVER, + 'actor_type' => \PluginFormcreatorTarget_Actor::ACTOR_TYPE_VALIDATOR + ] + ]); + $this->boolean($requesterActor->isNewItem())->isFalse(); + $this->boolean($observerActor->isNewItem())->isFalse(); + + // check the settings of the default actors + $this->integer((int) $requesterActor->getField('use_notification')) + ->isEqualTo(1); + $this->integer((int) $observerActor->getField('use_notification')) + ->isEqualTo(1); + } +} diff --git a/tests/2-integration/PluginFormcreatorTargetTicket.php b/tests/2-integration/PluginFormcreatorTargetTicket.php index ef785d00b..01c927a80 100644 --- a/tests/2-integration/PluginFormcreatorTargetTicket.php +++ b/tests/2-integration/PluginFormcreatorTargetTicket.php @@ -46,31 +46,31 @@ public function testTargetTicketActors() { // Create a form with a target ticket $form = $this->getForm(); - $targetTicket = new \PluginFormcreatorTargetTicket(); - $targetTicket->add([ + $instance = new \PluginFormcreatorTargetTicket(); + $instance->add([ 'name' => 'a target', 'plugin_formcreator_forms_id' => $form->getID() ]); - $targetTicket->getFromDB($targetTicket->getID()); - $this->boolean($targetTicket->isNewItem())->isFalse(); + $instance->getFromDB($instance->getID()); + $this->boolean($instance->isNewItem())->isFalse(); // find the actors created by default $requesterActor = new \PluginFormcreatorTarget_Actor(); $observerActor = new \PluginFormcreatorTarget_Actor(); - $targetTicketId = $targetTicket->getID(); + $instanceId = $instance->getID(); $requesterActor->getFromDBByCrit([ 'AND' => [ - 'itemtype' => $targetTicket->getType(), - 'items_id' => $targetTicketId, + 'itemtype' => $instance->getType(), + 'items_id' => $instanceId, 'actor_role' => \PluginFormcreatorTarget_Actor::ACTOR_ROLE_REQUESTER, 'actor_type' => \PluginFormcreatorTarget_Actor::ACTOR_TYPE_AUTHOR, ] ]); $observerActor->getFromDBByCrit([ 'AND' => [ - 'itemtype' => $targetTicket->getType(), - 'items_id' => $targetTicketId, + 'itemtype' => $instance->getType(), + 'items_id' => $instanceId, 'actor_role' => \PluginFormcreatorTarget_Actor::ACTOR_ROLE_OBSERVER, 'actor_type' => \PluginFormcreatorTarget_Actor::ACTOR_TYPE_VALIDATOR ] diff --git a/tests/3-unit/PluginFormcreatorTargetProblem.php b/tests/3-unit/PluginFormcreatorTargetProblem.php new file mode 100644 index 000000000..74963e916 --- /dev/null +++ b/tests/3-unit/PluginFormcreatorTargetProblem.php @@ -0,0 +1,557 @@ +. + * --------------------------------------------------------------------- + * @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 + * --------------------------------------------------------------------- + */ + +namespace tests\units; +use GlpiPlugin\Formcreator\Tests\CommonTestCase; +use GlpiPlugin\Formcreator\Tests\PluginFormcreatorTargetProblemDummy; + +class PluginFormcreatorTargetProblem extends CommonTestCase { + + public function beforeTestMethod($method) { + parent::beforeTestMethod($method); + switch ($method) { + case 'testSetTargetEntity': + case 'testImport': + $this->boolean($this->login('glpi', 'glpi'))->isTrue(); + break; + } + } + + public function providerGetTypeName() { + return [ + [ + 'input' => 0, + 'expected' => 'Target problems', + ], + [ + 'input' => 1, + 'expected' => 'Target problem', + ], + [ + 'input' => 2, + 'expected' => 'Target problems', + ], + ]; + } + + /** + * @dataProvider providerGetTypeName + * @param integer $number + * @param string $expected + */ + public function testGetTypeName($number, $expected) { + $output = \PluginFormcreatorTargetProblem::getTypeName($number); + $this->string($output)->isEqualTo($expected); + } + + public function providerPrepareInputForUpdate() { + return [ + [ + 'input' => [ + 'name' => '', + 'content' => '', + 'sla_rule' => (string) \PluginFormcreatorTargetProblem::SLA_RULE_NONE, + 'ola_rule' => (string) \PluginFormcreatorTargetProblem::OLA_RULE_NONE, + ], + 'expected' => [ + ], + 'message' => 'The name cannot be empty!', + ], + [ + 'input' => [ + 'name' => 'something', + 'content' => '', + 'sla_rule' => (string) \PluginFormcreatorTargetProblem::SLA_RULE_NONE, + 'ola_rule' => (string) \PluginFormcreatorTargetProblem::OLA_RULE_NONE, + ], + 'expected' => [ + ], + 'message' => 'The description cannot be empty!', + ], + [ + 'input' => [ + 'name' => 'something', + 'content' => 'foo', + 'destination_entity' => \PluginFormcreatorTargetProblem::DESTINATION_ENTITY_SPECIFIC, + '_destination_entity_value_specific' => '0', + 'urgency_rule' => \PluginFormcreatorTargetProblem::URGENCY_RULE_SPECIFIC, + '_urgency_specific' => '3', + 'category_rule' => \PluginFormcreatorTargetProblem::CATEGORY_RULE_NONE, + 'category_question' => '0', + 'sla_rule' => (string) \PluginFormcreatorTargetProblem::SLA_RULE_NONE, + 'ola_rule' => (string) \PluginFormcreatorTargetProblem::OLA_RULE_NONE, + ], + 'expected' => [ + 'name' => 'something', + 'content' => 'foo', + 'destination_entity' => \PluginFormcreatorTargetProblem::DESTINATION_ENTITY_SPECIFIC, + 'destination_entity_value' => '0', + 'urgency_rule' => \PluginFormcreatorTargetProblem::URGENCY_RULE_SPECIFIC, + 'urgency_question' => '3', + 'category_rule' => \PluginFormcreatorTargetProblem::CATEGORY_RULE_NONE, + 'category_question' => '0', + ], + 'message' => null, + ], + ]; + } + + /** + * @dataProvider providerPrepareInputForUpdate + */ + public function testPrepareInputForUpdate($input, $expected, $message) { + $instance = $this->newTestedInstance(); + $output = $instance->prepareInputForUpdate($input); + + if ($message !== null) { + $this->sessionHasMessage($message, ERROR); + $this->array($output)->hasSize(0); + return; + } + + $this->string($output['name'])->isEqualTo($expected['name']); + $this->string($output['content'])->isEqualTo($expected['content']); + $this->string($output['name'])->isEqualTo($expected['name']); + $this->integer($output['destination_entity'])->isEqualTo($expected['destination_entity']); + $this->string($output['destination_entity_value'])->isEqualTo($expected['destination_entity_value']); + $this->integer($output['urgency_rule'])->isEqualTo($expected['urgency_rule']); + $this->string($output['urgency_question'])->isEqualTo($expected['urgency_question']); + $this->integer($output['category_rule'])->isEqualTo($expected['category_rule']); + $this->string($output['category_question'])->isEqualTo($expected['category_question']); + } + + public function testGetEnumUrgencyRule() { + $output = \PluginFormcreatorTargetProblem::getEnumUrgencyRule(); + $this->array($output)->isEqualTo([ + \PluginFormcreatorTargetTicket::URGENCY_RULE_NONE => 'Urgency from template or Medium', + \PluginFormcreatorTargetProblem::URGENCY_RULE_SPECIFIC => 'Specific urgency', + \PluginFormcreatorTargetProblem::URGENCY_RULE_ANSWER => 'Equals to the answer to the question', + ]); + } + + public function testGetEnumCategoryRule() { + $output = \PluginFormcreatorTargetProblem::getEnumCategoryRule(); + $this->array($output)->isEqualTo([ + \PluginFormcreatorTargetTicket::CATEGORY_RULE_NONE => 'Category from template or none', + \PluginFormcreatorTargetTicket::CATEGORY_RULE_SPECIFIC => 'Specific category', + \PluginFormcreatorTargetTicket::CATEGORY_RULE_ANSWER => 'Equals to the answer to the question', + \PluginFormcreatorTargetTicket::CATEGORY_RULE_LAST_ANSWER => 'Last valid answer', + ]); + } + + public function testGetItem_User() { + $instance = new PluginFormcreatorTargetProblemDummy(); + $output = $instance->publicGetItem_User(); + $this->object($output)->isInstanceOf(\Problem_User::class); + $this->boolean($output->isNewItem())->isTrue(); + } + + public function testGetItem_Group() { + $instance = new PluginFormcreatorTargetProblemDummy(); + $output = $instance->publicGetItem_Group(); + $this->object($output)->isInstanceOf(\Group_Problem::class); + $this->boolean($output->isNewItem())->isTrue(); + } + + public function testGetItem_Supplier() { + $instance = new PluginFormcreatorTargetProblemDummy(); + $output = $instance->publicGetItem_Supplier(); + $this->object($output)->isInstanceOf(\Problem_Supplier::class); + $this->boolean($output->isNewItem())->isTrue(); + } + + public function testGetItem_Item() { + $instance = new PluginFormcreatorTargetProblemDummy(); + $output = $instance->publicGetItem_Item(); + $this->object($output)->isInstanceOf(\Item_Problem::class); + $this->boolean($output->isNewItem())->isTrue(); + } + + public function testGetCategoryFilter() { + $instance = new PluginFormcreatorTargetProblemDummy(); + $output = $instance->publicGetCategoryFilter(); + $this->array($output)->isEqualTo([ + 'is_problem' => 1, + ]); + } + + public function testGetTaggableFields() { + $instance = new PluginFormcreatorTargetProblemDummy(); + $output = $instance->publicGetTaggableFields(); + $this->array($output)->isEqualTo([ + 'target_name', + 'content', + 'impactcontent', + 'causecontent', + 'symptomcontent', + ]); + } + + public function testGetTargetItemtypeName() { + $instance = new PluginFormcreatorTargetProblemDummy(); + $output = $instance->publicGetTargetItemtypeName(); + $this->string($output)->isEqualTo(\Problem::class); + } + + /** + * + * @return void + */ + public function testSetTargetEntity() { + global $CFG_GLPI; + + // Disable notification to avoid output to console + $CFG_GLPI['use_notifications'] = '0'; + + $form = $this->getForm(); + $formFk = \PluginFormcreatorForm::getForeignKeyField(); + $targetProblem = $this->getTargetProblem([ + $formFk => $form->getID(), + ]); + + // Use a dummy class to access protected methods + $instance = new PluginFormcreatorTargetProblemDummy(); + $instance->getFromDB($targetProblem->getID()); + + // Test current entity of the requester + $entity = new \Entity(); + $entityId = $entity->import([ + 'entities_id' => '0', + 'name' => $this->getUniqueString() + ]); + \Session::changeActiveEntities($entityId); + $targetProblem->update([ + 'id' => $targetProblem->getID(), + '_skip_checks' => true, + 'destination_entity' => \PluginFormcreatorTargetProblem::DESTINATION_ENTITY_CURRENT, + 'destination_entity_value' => '0', + ]); + $instance->getFromDB($targetProblem->getID()); + + // Disable notification to avoid output to console + $CFG_GLPI['use_notifications'] = '0'; + + $formAnswer = new \PluginFormcreatorFormAnswer(); + $formAnswer->add([ + 'plugin_formcreator_forms_id' => $form->getID(), + 'entities_id' => $entityId, + ]); + $formAnswer->getFromDB($formAnswer->getID()); + $requesterId = \Session::getLoginUserID(); + $output = $instance->publicSetTargetEntity([], $formAnswer, $requesterId); + $this->integer((int) $output['entities_id'])->isEqualTo($entityId); + + // Test requester's entity + $targetProblem->update([ + 'id' => $targetProblem->getID(), + '_skip_checks' => true, + 'destination_entity' => \PluginFormcreatorTargetProblem::DESTINATION_ENTITY_REQUESTER, + 'destination_entity_value' => '0', + ]); + $instance->getFromDB($targetProblem->getID()); + + // Disable notification to avoid output to console + $CFG_GLPI['use_notifications'] = '0'; + + $formAnswer = new \PluginFormcreatorFormAnswer(); + $formAnswer->add([ + 'plugin_formcreator_forms_id' => $form->getID(), + 'entities_id' => $entityId, + ]); + \Session::changeActiveEntities($entityId); + $requesterId = \Session::getLoginUserID(); + $output = $instance->publicSetTargetEntity([], $formAnswer, $requesterId); + $this->integer((int) $output['entities_id'])->isEqualTo(0); + + // Test requester's first entity (alphanumeric order) + $targetProblem->update([ + 'id' => $targetProblem->getID(), + '_skip_checks' => true, + 'destination_entity' => \PluginFormcreatorTargetProblem::DESTINATION_ENTITY_REQUESTER_DYN_FIRST, + 'destination_entity_value' => '0', + ]); + $instance->getFromDB($targetProblem->getID()); + $entityId = $entity->import([ + 'entities_id' => '0', + 'name' => $this->getUniqueString(), + ]); + $user = new \User(); + $user->add([ + 'name' => $this->getUniqueString(), + 'password' => 'passwd', + 'password2' => 'passwd', + '_profiles_id' => '3', // Admin + '_entities_id' => $entityId, + ]); + $entity = new \Entity(); + $profileUser = new \Profile_User(); + // A login resyncs a user. Must login nefore adding the dynamic profile + $this->boolean($this->login($user->fields['name'], 'passwd'))->isTrue(); + $profileUser->add([ + \User::getForeignKeyField() => $user->getID(), + \Profile::getForeignKeyField() => 4, // Super admin + \Entity::getForeignKeyField() => $entityId, + 'is_dynamic' => '1', + ]); + + // Disable notification to avoid output to console + $CFG_GLPI['use_notifications'] = '0'; + + $formAnswer = new \PluginFormcreatorFormAnswer(); + $formAnswer->add([ + 'plugin_formcreator_forms_id' => $form->getID(), + 'entities_id' => 0, + ]); + $requesterId = \Session::getLoginUserID(); + $output = $instance->publicSetTargetEntity([], $formAnswer, $requesterId); + $this->integer((int) $output['entities_id'])->isEqualTo($entityId); + + // Test requester's last entity (alphanumeric order) + $targetProblem->update([ + 'id' => $targetProblem->getID(), + '_skip_checks' => true, + 'destination_entity' => \PluginFormcreatorTargetProblem::DESTINATION_ENTITY_REQUESTER_DYN_LAST, + 'destination_entity_value' => '0', + ]); + $instance->getFromDB($targetProblem->getID()); + + // Disable notification to avoid output to console + $CFG_GLPI['use_notifications'] = '0'; + + $formAnswer = new \PluginFormcreatorFormAnswer(); + $formAnswer->add([ + 'plugin_formcreator_forms_id' => $form->getID(), + 'entities_id' => $entityId, + ]); + $requesterId = \Session::getLoginUserID(); + $output = $instance->publicSetTargetEntity([], $formAnswer, $requesterId); + $this->integer((int) $output['entities_id'])->isEqualTo($entityId); + + // Test specific entity + $this->boolean($this->login('glpi', 'glpi'))->isTrue(); + $entityId = $entity->import([ + 'entities_id' => '0', + 'name' => $this->getUniqueString(), + ]); + $targetProblem->update([ + 'id' => $targetProblem->getID(), + '_skip_checks' => true, + 'destination_entity' => \PluginFormcreatorTargetProblem::DESTINATION_ENTITY_SPECIFIC, + 'destination_entity_value' => "$entityId", + ]); + $instance->getFromDB($targetProblem->getID()); + + // Disable notification to avoid output to console + $CFG_GLPI['use_notifications'] = '0'; + + $formAnswer = new \PluginFormcreatorFormAnswer(); + $formAnswer->add([ + 'plugin_formcreator_forms_id' => $form->getID(), + 'entities_id' => 0, + ]); + $requesterId = \Session::getLoginUserID(); + $output = $instance->publicSetTargetEntity([], $formAnswer, $requesterId); + $this->integer((int) $output['entities_id'])->isEqualTo($entityId); + + // Test form's entity + $entityId = $entity->import([ + 'entities_id' => '0', + 'name' => $this->getUniqueString(), + ]); + $targetProblem->update([ + 'id' => $targetProblem->getID(), + '_skip_checks' => true, + 'destination_entity' => \PluginFormcreatorTargetProblem::DESTINATION_ENTITY_FORM, + 'destination_entity_value' => '0', + ]); + $form->update([ + 'id' => $form->getID(), + 'entities_id' => $entityId, + ]); + $instance->getFromDB($targetProblem->getID()); + + // Disable notification to avoid output to console + $CFG_GLPI['use_notifications'] = '0'; + + $formAnswer = new \PluginFormcreatorFormAnswer(); + $formAnswer->add([ + 'plugin_formcreator_forms_id' => $form->getID(), + 'entities_id' => 0, + ]); + $requesterId = \Session::getLoginUserID(); + $output = $instance->publicSetTargetEntity([], $formAnswer, $requesterId); + $this->integer((int) $output['entities_id'])->isEqualTo($entityId); + } + + public function testExport() { + $instance = $this->newTestedInstance(); + + // Try to export an empty item + $this->exception(function () use ($instance) { + $instance->export(); + })->isInstanceOf(\GlpiPlugin\Formcreator\Exception\ExportFailureException::class); + + // Prepare an item to export + $instance = $this->getTargetProblem(); + $instance->getFromDB($instance->getID()); + + // Export the item without the ID and with UUID + $output = $instance->export(false); + + // Test the exported data + $fieldsWithoutID = [ + 'name', + 'target_name', + 'content', + 'impactcontent', + 'causecontent', + 'symptomcontent', + 'urgency_rule', + 'urgency_question', + 'destination_entity', + 'destination_entity_value', + 'tag_type', + 'tag_questions', + 'tag_specifics', + 'category_rule', + 'category_question', + 'show_rule', + ]; + $extraFields = [ + '_problemtemplate', + '_actors', + 'conditions', + ]; + + $this->array($output) + ->hasKeys($fieldsWithoutID + $extraFields + ['uuid']) + ->hasSize(1 + count($fieldsWithoutID) + count($extraFields)); + + // Export the item without the UUID and with ID + $output = $instance->export(true); + $this->array($output) + ->hasKeys($fieldsWithoutID + $extraFields + ['id']) + ->hasSize(1 + count($fieldsWithoutID) + count($extraFields)); + } + + public function testImport() { + $form = $this->getForm(); + $uuid = plugin_formcreator_getUuid(); + $input = [ + 'name' => $this->getUniqueString(), + 'target_name' => $this->getUniqueString(), + '_problemtemplate' => '', + 'content' => $this->getUniqueString(), + 'impactcontent' => $this->getUniqueString(), + 'controlistcontent' => $this->getUniqueString(), + 'rolloutplancontent' => $this->getUniqueString(), + 'backoutplancontent' => $this->getUniqueString(), + 'checklistcontent' => $this->getUniqueString(), + 'due_date_rule' => \PluginFormcreatorTargetProblem::DUE_DATE_RULE_NONE, + 'due_date_question' => '0', + 'due_date_value' => '', + 'due_date_period' => '', + 'urgency_rule' => \PluginFormcreatorTargetProblem::URGENCY_RULE_NONE, + 'urgency_question' => '0', + 'validation_followup' => '1', + 'destination_entity' => '0', + 'destination_entity_value' => null, + 'tag_type' => \PluginFormcreatorTargetProblem::TAG_TYPE_NONE, + 'tag_questions' => '0', + 'tag_specifics' => '', + 'category_rule' => \PluginFormcreatorTargetProblem::CATEGORY_RULE_NONE, + 'category_question' => '0', + 'uuid' => $uuid, + ]; + + $linker = new \PluginFormcreatorLinker(); + $targetProblemId = \PluginFormcreatorTargetProblem::import($linker, $input, $form->getID()); + $this->integer($targetProblemId)->isGreaterThan(0); + + unset($input['uuid']); + + $this->exception( + function() use($linker, $input, $form) { + \PluginFormcreatorTargetProblem::import($linker, $input, $form->getID()); + } + )->isInstanceOf(\GlpiPlugin\Formcreator\Exception\ImportFailureException::class) + ->hasMessage('UUID or ID is mandatory for Target problem'); // passes + + $input['id'] = $targetProblemId; + $targetProblemId2 = \PluginFormcreatorTargetProblem::import($linker, $input, $form->getID()); + $this->integer((int) $targetProblemId)->isNotEqualTo($targetProblemId2); + + $this->newTestedInstance()->delete([ + 'id' => $targetProblemId2, + ]); + + // Check successful link with template + $templateName = 'problem template ' . $this->getUniqueString(); + $problemTemplate = new \ProblemTemplate(); + $problemTemplate->add([ + 'name' => $templateName, + 'entities_id' => 0, + 'is_recursive' => 1, + ]); + $this->boolean($problemTemplate->isNewItem())->isFalse(); + $input['_problemtemplate'] = $templateName; + + $linker = new \PluginFormcreatorLinker(); + $targetProblemId3 = \PluginFormcreatorTargetProblem::import($linker, $input, $form->getID()); + $this->integer((int) $targetProblemId)->isNotEqualTo($targetProblemId3); + $targetProblem = $this->newTestedInstance(); + $targetProblem->getFromDB($targetProblemId3); + $this->integer((int) $targetProblem->fields['problemtemplates_id']) + ->isEqualTo($problemTemplate->getID()); + } + + public function testIsEntityAssign() { + $instance = $this->newTestedInstance(); + $this->boolean($instance->isEntityAssign())->isFalse(); + } + + public function testdeleteObsoleteItems() { + $form = $this->getForm(); + $targetProblem1 = $this->getTargetProblem([ + 'plugin_formcreator_forms_id' => $form->getID(), + ]); + $targetProblem2 = $this->getTargetProblem([ + 'plugin_formcreator_forms_id' => $form->getID(), + ]); + $instance = $this->newTestedInstance(); + $instance->deleteObsoleteItems($form, [$targetProblem2->getID()]); + + $checkDeleted = $this->newTestedInstance(); + $this->boolean($checkDeleted->getFromDB($targetProblem1->getID()))->isFalse(); + $checkDeleted = $this->newTestedInstance(); + $this->boolean($checkDeleted->getFromDB($targetProblem2->getID()))->isTrue(); + } +} diff --git a/tests/src/CommonTestCase.php b/tests/src/CommonTestCase.php index f6eec882b..9af86d87e 100644 --- a/tests/src/CommonTestCase.php +++ b/tests/src/CommonTestCase.php @@ -294,6 +294,22 @@ protected function getFormAnswer(array $input): ?\PluginFormcreatorFormAnswer { return $formAnswer; } + protected function getTargetProblem($input = []) { + if (!isset($input['name'])) { + $input['name'] = $this->getUniqueString(); + } + + $formFk = \PluginFormcreatorForm::getForeignKeyField(); + if (!isset($input[$formFk])) { + $input[$formFk] = $this->getForm()->getID(); + } + + $targetProblem = new \PluginFormcreatorTargetProblem(); + $targetProblem->add($input); + + return $targetProblem; + } + /** * Tests the session has a specific message * this may be replaced by a custom asserter for atoum diff --git a/tests/src/PluginFormcreatorTargetProblemDummy.php b/tests/src/PluginFormcreatorTargetProblemDummy.php new file mode 100644 index 000000000..c9df3a91e --- /dev/null +++ b/tests/src/PluginFormcreatorTargetProblemDummy.php @@ -0,0 +1,79 @@ +. + * --------------------------------------------------------------------- + * @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 + * --------------------------------------------------------------------- + */ + +namespace GlpiPlugin\Formcreator\Tests; + +class PluginFormcreatorTargetProblemDummy extends \PluginFormcreatorTargetProblem +{ + public static function getTable($classname = null) { + return \PluginFormcreatorTargetProblem::getTable(); + } + + public function publicSetTargetEntity($data, \PluginFormcreatorFormAnswer $formanswer, $requesters_id) { + return $this->setTargetEntity($data, $formanswer, $requesters_id); + } + + public function publicPrepareTemplate($template, \PluginFormcreatorFormAnswer $formAnswer, $disableRichText = false) { + return $this->prepareTemplate($template, $formAnswer, $disableRichText); + } + + public function publicGetItem_User() { + return $this->getItem_User(); + } + + public function publicGetItem_Group() { + return $this->getItem_Group(); + } + + public function publicGetItem_Supplier() { + return $this->getItem_Supplier(); + } + + public function publicGetItem_Item() { + return $this->getItem_Item(); + } + + public function publicGetItem_Actor() { + return $this->getItem_Actor(); + } + + public function publicGetCategoryFilter() { + return $this->getCategoryFilter(); + } + + public function publicGetTaggableFields() { + return $this->getTaggableFields(); + } + + public function publicGetTargetItemtypeName() { + return $this->getTargetItemtypeName(); + } +}