From 7800c3b110ee4305edb20cc95ab022b846d086f4 Mon Sep 17 00:00:00 2001 From: Thierry Bugier Date: Tue, 26 May 2020 14:06:58 +0200 Subject: [PATCH 1/3] fix: class should not be accessed directly Signed-off-by: Thierry Bugier --- inc/conditionnable.class.php | 4 ++++ inc/conditionnableinterface.class.php | 4 ++++ inc/duplicatableinterface.class.php | 4 ++++ inc/questionparameter.class.php | 5 +++++ inc/questionparameterinterface.class.php | 3 +++ 5 files changed, 20 insertions(+) diff --git a/inc/conditionnable.class.php b/inc/conditionnable.class.php index 4e54ba41d..ac9bf094a 100644 --- a/inc/conditionnable.class.php +++ b/inc/conditionnable.class.php @@ -29,6 +29,10 @@ * --------------------------------------------------------------------- */ +if (!defined('GLPI_ROOT')) { + die("Sorry. You can't access this file directly"); +} + trait PluginFormcreatorConditionnable { public function updateConditions($input) { diff --git a/inc/conditionnableinterface.class.php b/inc/conditionnableinterface.class.php index 00d5125a5..9da7eb45d 100644 --- a/inc/conditionnableinterface.class.php +++ b/inc/conditionnableinterface.class.php @@ -29,6 +29,10 @@ * --------------------------------------------------------------------- */ +if (!defined('GLPI_ROOT')) { + die("Sorry. You can't access this file directly"); +} + interface PluginFormcreatorConditionnableInterface { /** diff --git a/inc/duplicatableinterface.class.php b/inc/duplicatableinterface.class.php index 35bfc2d72..cc08ede7d 100644 --- a/inc/duplicatableinterface.class.php +++ b/inc/duplicatableinterface.class.php @@ -29,6 +29,10 @@ * --------------------------------------------------------------------- */ +if (!defined('GLPI_ROOT')) { + die("Sorry. You can't access this file directly"); +} + interface PluginFormcreatorDuplicatableInterface { /** diff --git a/inc/questionparameter.class.php b/inc/questionparameter.class.php index a839e0b9e..07b1f5787 100644 --- a/inc/questionparameter.class.php +++ b/inc/questionparameter.class.php @@ -28,6 +28,11 @@ * @link http://plugins.glpi-project.org/#/plugin/formcreator * --------------------------------------------------------------------- */ + +if (!defined('GLPI_ROOT')) { + die("Sorry. You can't access this file directly"); +} + abstract class PluginFormcreatorQuestionParameter extends CommonDBChild implements PluginFormcreatorQuestionParameterInterface, PluginFormcreatorExportableInterface diff --git a/inc/questionparameterinterface.class.php b/inc/questionparameterinterface.class.php index 229c3e239..562eea4d3 100644 --- a/inc/questionparameterinterface.class.php +++ b/inc/questionparameterinterface.class.php @@ -28,6 +28,9 @@ * @link http://plugins.glpi-project.org/#/plugin/formcreator * --------------------------------------------------------------------- */ +if (!defined('GLPI_ROOT')) { + die("Sorry. You can't access this file directly"); +} interface PluginFormcreatorQuestionParameterInterface { /** From 311335192a342b6b4370fed4edab8c2f499fe962 Mon Sep 17 00:00:00 2001 From: Thierry Bugier Date: Wed, 27 May 2020 09:10:48 +0200 Subject: [PATCH 2/3] refactor: factorize export /import Signed-off-by: Thierry Bugier --- inc/condition.class.php | 7 +- inc/exportable.class.php | 150 ++++++++++++++++++ inc/exportableinterface.class.php | 11 ++ inc/form.class.php | 245 ++++-------------------------- inc/form_profile.class.php | 2 + inc/form_validator.class.php | 3 +- inc/item_targetticket.class.php | 154 ++++++++++++------- inc/linker.class.php | 23 +++ inc/question.class.php | 1 + inc/questionparameter.class.php | 1 + inc/section.class.php | 81 ++-------- inc/target_actor.class.php | 2 + inc/targetbase.class.php | 1 + inc/targetchange.class.php | 60 ++------ inc/targetticket.class.php | 93 +++--------- 15 files changed, 378 insertions(+), 456 deletions(-) create mode 100644 inc/exportable.class.php diff --git a/inc/condition.class.php b/inc/condition.class.php index fb92436ab..1948534ac 100644 --- a/inc/condition.class.php +++ b/inc/condition.class.php @@ -35,8 +35,13 @@ die("Sorry. You can't access this file directly"); } -class PluginFormcreatorCondition extends CommonDBTM implements PluginFormcreatorExportableInterface +class PluginFormcreatorCondition extends CommonDBChild implements PluginFormcreatorExportableInterface { + use PluginFormcreatorExportable; + + static public $itemtype = 'itemtype'; + static public $items_id = 'items_id'; + const SHOW_RULE_ALWAYS = 1; const SHOW_RULE_HIDDEN = 2; const SHOW_RULE_SHOWN = 3; diff --git a/inc/exportable.class.php b/inc/exportable.class.php new file mode 100644 index 000000000..3de15185b --- /dev/null +++ b/inc/exportable.class.php @@ -0,0 +1,150 @@ +. + * --------------------------------------------------------------------- + * @copyright Copyright © 2011 - 2019 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 + * --------------------------------------------------------------------- + */ + +if (!defined('GLPI_ROOT')) { + die("Sorry. You can't access this file directly"); +} + +trait PluginFormcreatorExportable +{ + /** + * Insert the export of sub items in the export + * + * @param array $subItems key/value pair list of sub items + * @param array $export the export of the object + * @param boolean $remove_uuid + * @return array + */ + public function exportChildrenObjects($subItems, $export, $remove_uuid = false) { + global $DB; + + $fk = static::getForeignKeyField(); + foreach ($subItems as $key => $itemtypes) { + if (!is_array($itemtypes)) { + $itemtypes = [$itemtypes]; + } + $export[$key] = []; + foreach ($itemtypes as $itemtype) { + // $itemtype may be a CommonDBRelation type + // In such case it is still to the itemtype to build the export data + // because it may contain additinal data + // @see PluginFormcreatorItem_Ticket and its attribute 'link' + $list = []; + $allSubItems = $itemtype::getSQLCriteriaToSearchForItem($this->getType(), $this->getID()); + foreach ($DB->request($allSubItems) as $row) { + /** @var CommonDBConnexity $subItem */ + $subItem = new $itemtype(); + $subItem->getFromDB($row['id']); + if (is_subclass_of($subItem, CommonDBRelation::class)) { + if ($row['itemtype_1'] == $row['itemtype_2'] && $row['is_1']) { + // the linked object is the same itemtype as the parent's itemtype + // this relation will be also exported in the reverse order + // Let's ignore it + // TODO: if someday an CommonDBRelation itemtype links 2 objects + // belonging to different forms, then we must ignore the relation + // only when the 2 linked objects belong to the same form. + // This will needs an extra check here. + continue; + } + } + $list[] = $subItem->export($remove_uuid); + } + if (!is_array($subItems[$key])) { + $export[$key] = $list; + } else { + $export[$key][$itemtype] = $list; + } + } + } + + return $export; + } + + /** + * Import children objects + * + * @param array PluginFormcreatorExportableInterface $item + * @param PluginFormcreatorLinker $linker + * @param array $input + * @return void + */ + public function importChildrenObjects($item, $linker, $subItems, $input) { + $itemId = $item->getID(); + foreach ($subItems as $key => $itemtypes) { + if (!is_array($itemtypes)) { + if (!isset($input[$key])) { + $input[$key] = []; + } + $input[$key] = [$itemtypes => $input[$key]]; + $itemtypes = [$itemtypes]; + } + foreach ($itemtypes as $itemtype) { + $importedItems = []; + if (!isset($input[$key][$itemtype])) { + continue; + } + foreach ($input[$key][$itemtype] as $subInput) { + $importedItem = $itemtype::import( + $linker, + $subInput, + $itemId + ); + + // If $importedItem === false the item import is postponed + if ($importedItem !== false) { + $importedItems[] = $importedItem; + } + } + // Delete all other restrictions + $subItem = new $itemtype(); + $subItem->deleteObsoleteItems($item, $importedItems); + } + } + } + + public function deleteObsoleteItems(CommonDBTM $container, array $exclude) + { + if ($this instanceof CommonDBChild) { + $keepCriteria = [ + 'itemtype' => $container->getType(), + 'items_id' => $container->getID(), + ]; + } else { + $keepCriteria = [ + $container::getForeignKeyField() => $container->getID(), + ]; + } + if (count($exclude) > 0) { + $keepCriteria[] = ['NOT' => ['id' => $exclude]]; + } + return $this->deleteByCriteria($keepCriteria); + } +} \ No newline at end of file diff --git a/inc/exportableinterface.class.php b/inc/exportableinterface.class.php index b90c4d576..c81d8a4af 100644 --- a/inc/exportableinterface.class.php +++ b/inc/exportableinterface.class.php @@ -53,4 +53,15 @@ public function export($remove_uuid = false); * @return integer|false the id of the imported item or false on error */ public static function import(PluginFormcreatorLinker $linker, $input = [], $containerId = 0); + + /** + * Delete all items belonging to a container and not in the list of items to keep + * + * Used when importing objects. Items not matching imported objects are deleted + * @param CommonDBTM $container instance of the object containing items of + * @param array $exclude list of ID to keep + * + * @return boolean + */ + public function deleteObsoleteItems(CommonDBTM $container, array $exclude); } diff --git a/inc/form.class.php b/inc/form.class.php index b0e351654..6325c8170 100644 --- a/inc/form.class.php +++ b/inc/form.class.php @@ -41,6 +41,7 @@ class PluginFormcreatorForm extends CommonDBTM implements PluginFormcreatorConditionnableInterface { use PluginFormcreatorConditionnable; + use PluginFormcreatorExportable; static $rightname = 'entity'; @@ -1627,117 +1628,47 @@ public static function countAvailableForm() { } function export($remove_uuid = false) { - global $DB; - if ($this->isNewItem()) { return false; } - $formFk = PluginFormcreatorForm::getForeignKeyField(); - $form = $this->fields; - $form_section = new PluginFormcreatorSection; - $form_validator = new PluginFormcreatorForm_Validator; - $form_profile = new PluginFormcreatorForm_Profile; + $export = $this->fields; // replace entity id - $form['_entity'] + $export['_entity'] = Dropdown::getDropdownName(Entity::getTable(), - $form['entities_id']); + $export['entities_id']); // replace form category id - $form['_plugin_formcreator_category'] = ''; - if ($form['plugin_formcreator_categories_id'] > 0) { - $form['_plugin_formcreator_category'] + $export['_plugin_formcreator_category'] = ''; + if ($export['plugin_formcreator_categories_id'] > 0) { + $export['_plugin_formcreator_category'] = Dropdown::getDropdownName(PluginFormcreatorCategory::getTable(), - $form['plugin_formcreator_categories_id']); + $export['plugin_formcreator_categories_id']); } // remove non needed keys - unset($form['plugin_formcreator_categories_id'], - $form['entities_id'], - $form['usage_count']); - - // restrictions - $form['_profiles'] = []; - $all_profiles = $DB->request([ - 'SELECT' => ['id'], - 'FROM' => $form_profile::getTable(), - 'WHERE' => [ - $formFk => $this->getID() - ] - ]); - foreach ($all_profiles as $profile) { - $form_profile->getFromDB($profile['id']); - $form['_profiles'][] = $form_profile->export($remove_uuid); - } - - // get sections - $form['_sections'] = []; - $all_sections = $DB->request([ - 'SELECT' => ['id'], - 'FROM' => $form_section::getTable(), - 'WHERE' => [ - $formFk => $this->getID() - ] - ]); - foreach ($all_sections as $section) { - $form_section->getFromDB($section['id']); - $form['_sections'][] = $form_section->export($remove_uuid); - } - - // get submit conditions - $form['_conditions'] = []; - $condition = new PluginFormcreatorCondition(); - $all_conditions = $condition->getConditionsFromItem($this); - foreach ($all_conditions as $condition) { - $form['_conditions'][] = $condition->export($remove_uuid); - } - - // get validators - $form['_validators'] = []; - $all_validators = $DB->request([ - 'SELECT' => ['id'], - 'FROM' => $form_validator::getTable(), - 'WHERE' => [ - 'plugin_formcreator_forms_id' => $this->getID() - ] - ]); - foreach ($all_validators as $validator) { - $form_validator->getFromDB($validator['id']); - $form['_validators'][] = $form_validator->export($remove_uuid); - } - - // get targets - $form['_targets'] = []; - $all_targets = $this->getTargetsFromForm(); - foreach ($all_targets as $targetType => $targets) { - foreach ($targets as $target) { - $form['_targets'][$target->getType()][] = $target->export($remove_uuid); - } - } - - // get validators - $form['_validators'] = []; - $all_validators = $DB->request([ - 'SELECT' => ['id'], - 'FROM' => $form_validator::getTable(), - 'WHERE' => [ - $formFk => $this->getID() - ] - ]); - foreach ($all_validators as $validator) { - $form_validator->getFromDB($validator['id']); - $form['_validators'][] = $form_validator->export($remove_uuid); - } + unset($export['plugin_formcreator_categories_id'], + $export['entities_id'], + $export['usage_count']); + + $subItems = [ + '_profiles' => PluginFormcreatorForm_Profile::class, + '_sections' => PluginFormcreatorSection::class, + '_conditions' => PluginFormcreatorCondition::class, + '_targets' => (new self())->getTargetTypes(), + '_validators' => PluginFormcreatorForm_Validator::class, + ]; + $export = $this->exportChildrenObjects($subItems, $export, $remove_uuid); // remove ID or UUID $idToRemove = 'id'; if ($remove_uuid) { $idToRemove = 'uuid'; } - unset($form[$idToRemove]); + unset($export[$idToRemove]); - return $form; + return $export; } /** @@ -1890,7 +1821,6 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con throw new ImportFailureException('UUID or ID is mandatory'); } - $formFk = PluginFormcreatorForm::getForeignKeyField(); $item = new self(); // Find an existing form to update, only if an UUID is available $itemId = false; @@ -1974,127 +1904,14 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con // add the form to the linker $linker->addObject($originalId, $item); - // import form_profiles - if (isset($input['_profiles'])) { - $importedItems = []; - foreach ($input['_profiles'] as $formProfile) { - $importedItem = PluginFormcreatorForm_Profile::import( - $linker, - $formProfile, - $itemId - ); - if ($importedItem === false) { - // Falied to import a form_profile - return false; - } - $importedItems[] = $importedItem; - } - // Delete all other restrictions - if (count($importedItems) > 0) { - $FormProfile = new PluginFormcreatorForm_Profile(); - $FormProfile->deleteByCriteria([ - $formFk => $itemId, - ['NOT' => ['id' => $importedItems]] - ]); - } - } - - // import form's sections - if (isset($input['_sections'])) { - // sort questions by order - usort($input['_sections'], function ($a, $b) { - if ($a['order'] == $b['order']) { - return 0; - } - return ($a['order'] < $b['order']) ? -1 : 1; - }); - - // Import each section - $importedItems = []; - foreach ($input['_sections'] as $section) { - $importedItem = PluginFormcreatorSection::import( - $linker, - $section, - $itemId - ); - if ($importedItem === false) { - // Falied to import a section - return false; - } - $importedItems[] = $importedItem; - } - // Delete all other sections - $deleteCriteria = []; - if (count($importedItems) > 0) { - $deleteCriteria = ['NOT' => ['id' => $importedItems]]; - } - $FormProfile = new PluginFormcreatorSection(); - $FormProfile->deleteByCriteria([ - $formFk => $itemId, - $deleteCriteria, - ]); - } - - // Import submit conditions - if (isset($input['_conditions'])) { - foreach ($input['_conditions'] as $condition) { - PluginFormcreatorCondition::import($linker, $condition, $itemId); - } - } - - // import form's targets - if (isset($input['_targets'])) { - foreach ((new self())->getTargetTypes() as $targetType) { - // import targets - $importedItems = []; - if (isset($input['_targets'][$targetType])) { - foreach ($input['_targets'][$targetType] as $targetData) { - $importedItem = $targetType::import( - $linker, - $targetData, - $itemId - ); - if ($importedItem === false) { - // Falied to import a section - return false; - } - $importedItems[] = $importedItem; - } - } - // delete other targets of the itemtype $targetType - if (count($importedItems)) { - $target = new $targetType(); - $target->deleteByCriteria([ - $formFk => $itemId, - ['NOT' => ['id' => $importedItems]] - ]); - } - } - } - - // Import validators - if (isset($input['_validators'])) { - $importedItems = []; - foreach ($input['_validators'] as $validator) { - $importedItem = PluginFormcreatorForm_Validator::import( - $linker, - $validator, - $itemId - ); - if ($importedItem === false) { - // Failed to import a section - return false; - } - $importedItems[] = $importedItem; - } - if (count($importedItems)) { - $form_validator = new PluginFormcreatorForm_Validator; - $form_validator->deleteByCriteria([ - $formFk => $itemId, - ['NOT' => ['id' => $importedItems]] - ]); - } - } + $subItems = [ + '_profiles' => PluginFormcreatorForm_Profile::class, + '_sections' => PluginFormcreatorSection::class, + '_conditions' => PluginFormcreatorCondition::class, + '_targets' => (new self())->getTargetTypes(), + '_validators' => PluginFormcreatorForm_Validator::class, + ]; + $item->importChildrenObjects($item, $linker, $subItems, $input); return $itemId; } @@ -2520,4 +2337,6 @@ public static function getFormRestrictionCriterias($formTable = '') { return $restriction; } + + public function deleteObsoleteItems(CommonDBTM $container, array $exclude) {} } diff --git a/inc/form_profile.class.php b/inc/form_profile.class.php index 59e369dda..58d35e961 100644 --- a/inc/form_profile.class.php +++ b/inc/form_profile.class.php @@ -36,6 +36,8 @@ class PluginFormcreatorForm_Profile extends CommonDBRelation implements PluginFormcreatorExportableInterface { + use PluginFormcreatorExportable; + static public $itemtype_1 = PluginFormcreatorForm::class; static public $items_id_1 = 'plugin_formcreator_forms_id'; static public $itemtype_2 = Profile::class; diff --git a/inc/form_validator.class.php b/inc/form_validator.class.php index a9a69dd6c..9dbbbbd96 100644 --- a/inc/form_validator.class.php +++ b/inc/form_validator.class.php @@ -42,6 +42,7 @@ class PluginFormcreatorForm_Validator extends CommonDBRelation implements PluginFormcreatorExportableInterface { + use PluginFormcreatorExportable; // From CommonDBRelation static public $itemtype_1 = PluginFormcreatorForm::class; @@ -158,7 +159,7 @@ public function export($remove_uuid = false) { } /** - * Get validators of type $itemtype associated to a form + * Get validators of type $itemtype associated to a form * * @param PluginFormcreatorForm $form * @param string $itemtype diff --git a/inc/item_targetticket.class.php b/inc/item_targetticket.class.php index 3de8739f8..8dbfe7c1a 100644 --- a/inc/item_targetticket.class.php +++ b/inc/item_targetticket.class.php @@ -29,82 +29,118 @@ * --------------------------------------------------------------------- */ +use GlpiPlugin\Formcreator\Exception\ImportFailureException; + if (!defined('GLPI_ROOT')) { die("Sorry. You can't access this file directly"); } class PluginFormcreatorItem_TargetTicket extends CommonDBRelation +implements PluginFormcreatorExportableInterface { + use PluginFormcreatorExportable; static public $itemtype_1 = 'itemtype'; static public $items_id_1 = 'items_id'; static public $itemtype_2 = PluginFormcreatorTargetTicket::class; static public $items_id_2 = 'plugin_formcreator_targettickets_id'; - static public $logs_for_item_1 = false; + static public $logs_for_item_1 = false; - /** - * Export in an array all the data of the current instanciated form - * - * @param boolean $remove_uuid remove the uuid key - * - * @return array the array with all data (with sub tables) - */ public function export($remove_uuid = false) { if ($this->isNewItem()) { return false; } - $item_targetTicket = $this->fields; + $export = $this->fields; // remove non needed keys $targetTicketFk = PluginFormcreatorTargetTicket::getForeignKeyField(); - $this->convertIds($item_targetTicket); - unset($item_targetTicket[$targetTicketFk]); + unset($export[$targetTicketFk]); // remove ID or UUID $idToRemove = 'id'; if ($remove_uuid) { $idToRemove = 'uuid'; } - unset($item_targetTicket[$idToRemove]); + unset($export[$idToRemove]); + + // This is a CommonDBRelation object + // We must output the object of the 1st relation + // @see PluginFormcreatorExportable::exportChildrenObjects() + $linkedItemtype = $export['itemtype']; + $linkedItem = new $linkedItemtype(); + $linkedItemId = $export['items_id']; + $linkedItem->getFromDBByCrit([ + 'id' => $linkedItemId + ]); + if ($linkedItem->isNewItem()) { + // TODO: error linked item not found + } + $identifierColumn = 'id'; + if (!$remove_uuid && strpos($export['itemtype'], 'PluginFormcreator') === 0) { + $identifierColumn = 'uuid'; + } + $export['items_id'] = $linkedItem->fields[$identifierColumn]; - return $item_targetTicket; + return $export; } - public static function import($targetTicket_id, $item_targetTicket = [], $storeOnly = true) { - static $relationsToImport = []; - - if ($storeOnly) { - $item_targetTicket['plugin_formcreator_targettickets_id'] = $targetTicket_id; + public static function import(PluginFormcreatorLinker $linker, $input = [], $containerId = 0) { + if (!isset($input['uuid']) && !isset($input['id'])) { + throw new ImportFailureException('UUID or ID is mandatory'); + } - $item = new static(); - if ($item_targetTicket_id = plugin_formcreator_getFromDBByField($item, 'uuid', $item_targetTicket['uuid'])) { - // add id key - $item_targetTicket['id'] = $item_targetTicket_id; + $targetTicketFk = PluginFormcreatorTargetTicket::getForeignKeyField(); + $input[$targetTicketFk] = $containerId; + $input['_skip_checks'] = 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'] + ); + } - // prepare update item_target ticket - $relationsToImport[] = $item_targetTicket; - } else { - // prepare create item_target ticket - $relationsToImport[] = $item_targetTicket; + // set ID for linked objects + $linkedItemtype = $input['itemtype']; + $linkedItemId = $input['items_id']; + $linkedItem = $linker->findObject($linkedItemtype, $idKey, $linkedItemId); + if ($linkedItem->isNewItem()) { + if (strpos($linkedItemtype, 'PluginFormcreator') === 0) { + // the linnked object belongs to the plugin, maybe the item will be imported later + $linker->postpone($input[$idKey], $item->getType(), $input, $containerId); + return false; } + // linked item is not an object of Formcreator, it will not be imported + throw new ImportFailureException('Failed to find a linked object to a target ticket'); + } + + // Add or update + $originalId = $input[$idKey]; + if ($itemId !== false) { + $input['id'] = $itemId; + $item->update($input); } else { - // Assumes all target tickets needed for the stored conditions exist - foreach ($relationsToImport as $item_targetTicket) { - $item = new static(); - $linkedItem = new $item_targetTicket['itemtype'](); - if ($item_targetTicket['itemtype'] == PluginFormcreatorTargetTicket::getType()) { - $item_targetTicket['items_id'] = plugin_formcreator_getFromDBByField($linkedItem, 'uuid', $item_targetTicket['items_id']); - } - if (isset($item_targetTicket['id'])) { - $item->update($item_targetTicket); - } else { - $item->add($item_targetTicket); - } - } - $relationsToImport = []; + 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); + + return $itemId; } public function prepareInputForAdd($input) { @@ -117,22 +153,22 @@ public function prepareInputForAdd($input) { return $input; } - protected function convertIds(&$parameter) { - if ($parameter['itemtype'] == PluginFormcreatorTargetTicket::getType()) { - $targetTicket = new PluginFormcreatorTargetTicket(); - $targetTicket->getFromDB($parameter['items_id']); - $parameter['items_id'] = $targetTicket->fields['uuid']; - } - } - - protected function convertUuids(&$parameter) { - if ($questionId2 - = plugin_formcreator_getFromDBByField(new PluginFormcreatorQuestion(), - 'uuid', - $parameter['plugin_formcreator_questions_id_2'])) { - $parameter['plugin_formcreator_questions_id_2'] = $questionId2; - return true; - } - return false; - } + // protected function convertIds(&$parameter) { + // if ($parameter['itemtype'] == PluginFormcreatorTargetTicket::getType()) { + // $targetTicket = new PluginFormcreatorTargetTicket(); + // $targetTicket->getFromDB($parameter['items_id']); + // $parameter['items_id'] = $targetTicket->fields['uuid']; + // } + // } + + // protected function convertUuids(&$parameter) { + // if ($questionId2 + // = plugin_formcreator_getFromDBByField(new PluginFormcreatorQuestion(), + // 'uuid', + // $parameter['plugin_formcreator_questions_id_2'])) { + // $parameter['plugin_formcreator_questions_id_2'] = $questionId2; + // return true; + // } + // return false; + // } } diff --git a/inc/linker.class.php b/inc/linker.class.php index 88ebf38e2..3e62375a5 100644 --- a/inc/linker.class.php +++ b/inc/linker.class.php @@ -74,12 +74,35 @@ public function getObjectsByType($itemtype) { return $this->imported[$itemtype]; } + /** + * Find an object in the DB + * Contrary to getObject(), this method also searches in objects which + * are not and will not be imported + * + * @param string $itemtype itemtype of object to find + * @param integer $id ID of object to fiind + * @param string $idField fieldname where the ID is searched for + * @return void + */ + public function findObject($itemtype, $idField, $id) { + if (!strpos($itemtype, 'PluginFormcreator') !== 0) { + // The itemtype is not part of Formcreator + // Cannot use uuid column + $idField = 'id'; + } + $item = new $itemtype(); + plugin_formcreator_getFromDBByField($item, $idField, $id); + + return $item; + } + /** * Store input data of an object to add it later * * @param string|integer $originalId * @param string $itemtype * @param array $input + * @param integer $relationId * @return void */ public function postpone($originalId, $itemtype, array $input, $relationId) { diff --git a/inc/question.class.php b/inc/question.class.php index 086c0fc98..8211fd8cc 100644 --- a/inc/question.class.php +++ b/inc/question.class.php @@ -41,6 +41,7 @@ class PluginFormcreatorQuestion extends CommonDBChild implements PluginFormcreatorConditionnableInterface { use PluginFormcreatorConditionnable; + use PluginFormcreatorExportable; static public $itemtype = PluginFormcreatorSection::class; static public $items_id = 'plugin_formcreator_sections_id'; diff --git a/inc/questionparameter.class.php b/inc/questionparameter.class.php index 07b1f5787..d25806cc3 100644 --- a/inc/questionparameter.class.php +++ b/inc/questionparameter.class.php @@ -37,6 +37,7 @@ abstract class PluginFormcreatorQuestionParameter extends CommonDBChild implements PluginFormcreatorQuestionParameterInterface, PluginFormcreatorExportableInterface { + use PluginFormcreatorExportable; // From CommonDBRelation static public $itemtype = PluginFormcreatorQuestion::class; diff --git a/inc/section.class.php b/inc/section.class.php index 8751ffb49..fb29d1a51 100644 --- a/inc/section.class.php +++ b/inc/section.class.php @@ -41,6 +41,7 @@ class PluginFormcreatorSection extends CommonDBChild implements PluginFormcreatorConditionnableInterface { use PluginFormcreatorConditionnable; + use PluginFormcreatorExportable; static public $itemtype = PluginFormcreatorForm::class; static public $items_id = 'plugin_formcreator_forms_id'; @@ -264,92 +265,40 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con // add the section to the linker $linker->addObject($originalId, $item); - // Import each question - $importedItems = []; - if (isset($input['_questions'])) { - // sort questions by order - usort($input['_questions'], function ($a, $b) { - if ($a['order'] == $b['order']) { - return 0; - } - return ($a['order'] < $b['order']) ? -1 : 1; - }); - - foreach ($input['_questions'] as $question) { - $importedItem = PluginFormcreatorQuestion::import($linker, $question, $itemId); - if ($importedItem === false) { - // Falied to import a question - return false; - } - $importedItems[] = $importedItem; - } - } - // Delete all other questions - $deleteCriteria = []; - if (count($importedItems) > 0) { - $deleteCriteria = ['NOT' => ['id' => $importedItems]]; - } - $FormProfile = new PluginFormcreatorSection(); - $FormProfile->deleteByCriteria([ - $formFk => $itemId, - $deleteCriteria, - ]); - - // Import conditions - if (isset($input['_conditions'])) { - foreach ($input['_conditions'] as $condition) { - PluginFormcreatorCondition::import($linker, $condition, $itemId); - } - } + $subItems = [ + '_questions' => PluginFormcreatorQuestion::class, + '_conditions' => PluginFormcreatorCondition::class, + ]; + $item->importChildrenObjects($item, $linker, $subItems, $input); return $itemId; } public function export($remove_uuid = false) { - global $DB; - if ($this->isNewItem()) { return false; } - $section = $this->fields; + $export = $this->fields; // remove key and fk $formFk = PluginFormcreatorForm::getForeignKeyField(); - unset($section[$formFk]); + unset($export[$formFk]); - // get questions - $form_question = new PluginFormcreatorQuestion; - $section['_questions'] = []; - $all_questions = $DB->request([ - 'SELECT' => ['id'], - 'FROM' => $form_question::getTable(), - 'WHERE' => [ - self::getForeignKeyField() => $this->getID() - ] - ]); - foreach ($all_questions as $question) { - if ($form_question->getFromDB($question['id'])) { - $section['_questions'][] = $form_question->export($remove_uuid); - } - } - - // get section conditions - $section['_conditions'] = []; - $condition = new PluginFormcreatorCondition(); - $all_conditions = $condition->getConditionsFromItem($this); - foreach ($all_conditions as $condition) { - $section['_conditions'][] = $condition->export($remove_uuid); - } + $subItems = [ + '_questions' => PluginFormcreatorQuestion::class, + '_conditions' => PluginFormcreatorCondition::class, + ]; + $export = $this->exportChildrenObjects($subItems, $export, $remove_uuid); // remove ID or UUID $idToRemove = 'id'; if ($remove_uuid) { $idToRemove = 'uuid'; } - unset($section[$idToRemove]); + unset($export[$idToRemove]); - return $section; + return $export; } /** diff --git a/inc/target_actor.class.php b/inc/target_actor.class.php index cf4b93bcf..9e04e5933 100644 --- a/inc/target_actor.class.php +++ b/inc/target_actor.class.php @@ -37,6 +37,8 @@ abstract class PluginFormcreatorTarget_Actor extends CommonDBChild implements PluginFormcreatorExportableInterface { + use PluginFormcreatorExportable; + const ACTOR_TYPE_CREATOR = 1; const ACTOR_TYPE_VALIDATOR = 2; const ACTOR_TYPE_PERSON = 3; diff --git a/inc/targetbase.class.php b/inc/targetbase.class.php index cde799ae0..1af202733 100644 --- a/inc/targetbase.class.php +++ b/inc/targetbase.class.php @@ -39,6 +39,7 @@ abstract class PluginFormcreatorTargetBase extends CommonDBChild implements PluginFormcreatorConditionnableInterface { use PluginFormcreatorConditionnable; + use PluginFormcreatorExportable; static public $itemtype = PluginFormcreatorForm::class; static public $items_id = 'plugin_formcreator_forms_id'; diff --git a/inc/targetchange.class.php b/inc/targetchange.class.php index 5a453e8af..1b75a693c 100644 --- a/inc/targetchange.class.php +++ b/inc/targetchange.class.php @@ -102,44 +102,21 @@ protected function getTaggableFields() { * @return array the array with all data (with sub tables) */ public function export($remove_uuid = false) { - global $DB; - if ($this->isNewItem()) { return false; } - $target_data = $this->fields; + $export = $this->fields; // remove key and fk $formFk = PluginFormcreatorForm::getForeignKeyField(); - unset($target_data[$formFk]); - - // get target actors - $target_data['_actors'] = []; - $myFk = self::getForeignKeyField(); - $all_target_actors = $DB->request([ - 'SELECT' => ['id'], - 'FROM' => PluginFormcreatorTargetChange_Actor::getTable(), - 'WHERE' => [ - $myFk => $this->getID() - ] - ]); - - // Export sub items - $form_target_actor = $this->getItem_Actor(); - foreach ($all_target_actors as $target_actor) { - if ($form_target_actor->getFromDB($target_actor['id'])) { - $target_data['_actors'][] = $form_target_actor->export($remove_uuid); - } - } + unset($export[$formFk]); - // get conditions - $target_data['_conditions'] = []; - $condition = new PluginFormcreatorCondition(); - $all_conditions = $condition->getConditionsFromItem($this); - foreach ($all_conditions as $condition) { - $target_data['_conditions'][] = $condition->export($remove_uuid); - } + $subItems = [ + '_actors' => $this->getItem_Actor()->getType(), + '_conditions' => PluginFormcreatorCondition::class, + ]; + $export = $this->exportChildrenObjects($subItems, $export, $remove_uuid); // remove ID or UUID $idToRemove = 'id'; @@ -147,11 +124,11 @@ public function export($remove_uuid = false) { $idToRemove = 'uuid'; } else { // Convert IDs into UUIDs - $target_data = $this->convertTags($target_data); + $export = $this->convertTags($export); } - unset($target_data[$idToRemove]); + unset($export[$idToRemove]); - return $target_data; + return $export; } public static function import(PluginFormcreatorLinker $linker, $input = [], $containerId = 0) { @@ -228,18 +205,11 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con // add the target to the linker $linker->addObject($originalId, $item); - if (isset($input['_actors'])) { - foreach ($input['_actors'] as $actor) { - PluginFormcreatorTargetChange_Actor::import($linker, $actor, $itemId); - } - } - - // Import conditions - if (isset($input['_conditions'])) { - foreach ($input['_conditions'] as $condition) { - PluginFormcreatorCondition::import($linker, $condition, $itemId); - } - } + $subItems = [ + '_actors' => $item->getItem_Actor()->getType(), + '_conditions' => PluginFormcreatorCondition::class, + ]; + $item->importChildrenObjects($item, $linker, $subItems, $input); return $itemId; } diff --git a/inc/targetticket.class.php b/inc/targetticket.class.php index 9f75602eb..c1dd452b4 100644 --- a/inc/targetticket.class.php +++ b/inc/targetticket.class.php @@ -1096,24 +1096,12 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con // add the target to the linker $linker->addObject($originalId, $item); - if (isset($input['_actors'])) { - foreach ($input['_actors'] as $actor) { - PluginFormcreatorTargetTicket_Actor::import($linker, $actor, $itemId); - } - } - - if (isset($input['_ticket_relations'])) { - foreach ($input['_ticket_relations'] as $ticketLink) { - PluginFormcreatorItem_TargetTicket::import($linker, $ticketLink, $itemId); - } - } - - // Import conditions - if (isset($input['_conditions'])) { - foreach ($input['_conditions'] as $condition) { - PluginFormcreatorCondition::import($linker, $condition, $itemId); - } - } + $subItems = [ + '_actors' => $item->getItem_Actor()->getType(), + '_ticket_relations' => PluginFormcreatorItem_TargetTicket::class, + '_conditions' => PluginFormcreatorCondition::class, + ]; + $item->importChildrenObjects($item, $linker, $subItems, $input); return $itemId; } @@ -1130,68 +1118,31 @@ protected function getTaggableFields() { * @return array the array with all data (with sub tables) */ public function export($remove_uuid = false) { - global $DB; - if ($this->isNewItem()) { return false; } - $target_data = $this->fields; + $export = $this->fields; // remove key and fk $formFk = PluginFormcreatorForm::getForeignKeyField(); - unset($target_data[$formFk]); + unset($export[$formFk]); // replace dropdown ids - $target_data['_tickettemplate'] = ''; - if ($target_data['tickettemplates_id'] > 0) { - $target_data['_tickettemplate'] + $export['_tickettemplate'] = ''; + if ($export['tickettemplates_id'] > 0) { + $export['_tickettemplate'] = Dropdown::getDropdownName('glpi_tickettemplates', - $target_data['tickettemplates_id']); - } - unset($target_data['tickettemplates_id']); - - // get target actors - $target_data['_actors'] = []; - $myFk = self::getForeignKeyField(); - $all_target_actors = $DB->request([ - 'SELECT' => ['id'], - 'FROM' => PluginFormcreatorTargetTicket_Actor::getTable(), - 'WHERE' => [ - $myFk => $this->getID() - ] - ]); - - // Export sub items - $form_target_actor = $this->getItem_Actor(); - foreach ($all_target_actors as $target_actor) { - if ($form_target_actor->getFromDB($target_actor['id'])) { - $target_data['_actors'][] = $form_target_actor->export($remove_uuid); - } + $export['tickettemplates_id']); } + unset($export['tickettemplates_id']); - // get data from ticket relations - $target_data['_ticket_relations'] = []; - $target_ticketLink = new PluginFormcreatorItem_TargetTicket(); - $all_ticketLinks = $DB->request([ - 'SELECT' => ['id'], - 'FROM' => $target_ticketLink::getTable(), - 'WHERE' => [ - 'plugin_formcreator_targettickets_id' => $target_data['id'] - ], - ]); - foreach ($all_ticketLinks as $ticketLink) { - $target_ticketLink->getFromDB($ticketLink['id']); - $target_data['_ticket_relations'][] = $target_ticketLink->export($remove_uuid); - } - - // get conditions - $target_data['_conditions'] = []; - $condition = new PluginFormcreatorCondition(); - $all_conditions = $condition->getConditionsFromItem($this); - foreach ($all_conditions as $condition) { - $target_data['_conditions'][] = $condition->export($remove_uuid); - } + $subItems = [ + '_actors' => $this->getItem_Actor()->getType(), + '_ticket_relations' => PluginFormcreatorItem_TargetTicket::class, + '_conditions' => PluginFormcreatorCondition::class, + ]; + $export = $this->exportChildrenObjects($subItems, $export, $remove_uuid); // remove ID or UUID $idToRemove = 'id'; @@ -1199,11 +1150,11 @@ public function export($remove_uuid = false) { $idToRemove = 'uuid'; } else { // Convert IDs into UUIDs - $target_data = $this->convertTags($target_data); + $export = $this->convertTags($export); } - unset($target_data[$idToRemove]); + unset($export[$idToRemove]); - return $target_data; + return $export; } private function saveAssociatedItems($input) { From de2d2aa9942b6c5e696dd4b7754b5404f81652cf Mon Sep 17 00:00:00 2001 From: Thierry Bugier Date: Wed, 27 May 2020 18:27:16 +0200 Subject: [PATCH 3/3] fix(form): unused class usage Signed-off-by: Thierry Bugier --- inc/exportable.class.php | 1 - inc/form_validator.class.php | 1 - 2 files changed, 2 deletions(-) diff --git a/inc/exportable.class.php b/inc/exportable.class.php index 3de15185b..35fc839b1 100644 --- a/inc/exportable.class.php +++ b/inc/exportable.class.php @@ -46,7 +46,6 @@ trait PluginFormcreatorExportable public function exportChildrenObjects($subItems, $export, $remove_uuid = false) { global $DB; - $fk = static::getForeignKeyField(); foreach ($subItems as $key => $itemtypes) { if (!is_array($itemtypes)) { $itemtypes = [$itemtypes]; diff --git a/inc/form_validator.class.php b/inc/form_validator.class.php index 9dbbbbd96..a4b1dcba1 100644 --- a/inc/form_validator.class.php +++ b/inc/form_validator.class.php @@ -29,7 +29,6 @@ * --------------------------------------------------------------------- */ -use tests\units\PluginFormcreatorForm_Validator as TestsPluginFormcreatorForm_Validator; use GlpiPlugin\Formcreator\Exception\ImportFailureException; if (!defined('GLPI_ROOT')) {