diff --git a/front/form.form.php b/front/form.form.php index 850f6fd8f..9d7eb344c 100644 --- a/front/form.form.php +++ b/front/form.form.php @@ -113,6 +113,14 @@ Html::footer(); } else if (isset($_POST['import_send'])) { + Html::header( + PluginFormcreatorForm::getTypeName(2), + $_SERVER['PHP_SELF'], + 'admin', + 'PluginFormcreatorForm', + 'option' + ); + // Import form Session::checkRight('entity', UPDATE); $form->importJson($_REQUEST); diff --git a/inc/condition.class.php b/inc/condition.class.php index 0308c813b..f148026c0 100644 --- a/inc/condition.class.php +++ b/inc/condition.class.php @@ -165,6 +165,11 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con return $itemId; } + + public static function countItemsToImport($input) { + return 1; + } + /** * Export in an array all the data of the current instanciated condition * @param boolean $remove_uuid remove the uuid key diff --git a/inc/exportable.class.php b/inc/exportable.class.php index 1362d6971..53ca77aae 100644 --- a/inc/exportable.class.php +++ b/inc/exportable.class.php @@ -75,6 +75,7 @@ public function exportChildrenObjects($subItems, $export, $remove_uuid = false) * * @param array PluginFormcreatorExportableInterface $item * @param PluginFormcreatorLinker $linker + * @param $subItems * @param array $input * @return void */ @@ -111,4 +112,42 @@ public function importChildrenObjects($item, $linker, $subItems, $input) { } } } + + /** + * Count sub items + * + * @param array $input + * @param $subItems + * @return integer + */ + public static function countChildren($input, $subItems = []) { + if (count($subItems) < 1) { + return 1; + } + + $count = 0; + foreach($subItems as $key => $itemtypes) { + if (isset($input[$key])) { + // force array of itemetypes + if (!is_array($itemtypes)) { + if (!isset($input[$key])) { + $input[$key] = []; + } + $input[$key] = [$itemtypes => $input[$key]]; + $itemtypes = [$itemtypes]; + } + + foreach ($itemtypes as $itemtype) { + if (!isset($input[$key][$itemtype])) { + continue; + } + foreach ($input[$key][$itemtype] as $subInput) { + $count += $itemtype::countItemsToImport($subInput); + } + } + } + } + + return $count; + } } \ No newline at end of file diff --git a/inc/exportableinterface.class.php b/inc/exportableinterface.class.php index 50d281b47..dc828befc 100644 --- a/inc/exportableinterface.class.php +++ b/inc/exportableinterface.class.php @@ -64,4 +64,11 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con * @return boolean */ public function deleteObsoleteItems(CommonDBTM $container, array $exclude); + + /** get the count of inner objects to import + * @param array $input data to import + * + * return integer + */ + public static function countItemsToImport($input); } diff --git a/inc/form.class.php b/inc/form.class.php index f912e7749..cb87c803e 100644 --- a/inc/form.class.php +++ b/inc/form.class.php @@ -1841,10 +1841,17 @@ public function importJson($params = []) { continue; } + // Get the total count of objects to import, for the progressbar + $linker = new PluginFormcreatorLinker(); + foreach($forms_toimport['forms'] as $form) { + $linker->countItems($form, self::class); + } + $linker->initProgressBar(); + $success = true; foreach ($forms_toimport['forms'] as $form) { + $linker->reset(); set_time_limit(30); - $linker = new PluginFormcreatorLinker(); try { self::import($linker, $form); } catch (ImportFailureException $e) { @@ -1979,6 +1986,18 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con return $itemId; } + public static function countItemsToImport($input) { + // Code similar to ImportChildrenObjects + $subItems = [ + '_profiles' => PluginFormcreatorForm_Profile::class, + '_sections' => PluginFormcreatorSection::class, + '_conditions' => PluginFormcreatorCondition::class, + '_targets' => (new self())->getTargetTypes(), + '_validators' => PluginFormcreatorForm_Validator::class, + ]; + return 1 + self::countChildren($input, $subItems); + } + public function createDocumentType() { $documentType = new DocumentType(); $success = $documentType->add([ diff --git a/inc/form_profile.class.php b/inc/form_profile.class.php index 550ad7404..2ab50211a 100644 --- a/inc/form_profile.class.php +++ b/inc/form_profile.class.php @@ -251,6 +251,10 @@ public function export($remove_uuid = false) { return $form_profile; } + public static function countItemsToImport($input) { + return 1; + } + public function deleteObsoleteItems(CommonDBTM $container, array $exclude) { $keepCriteria = [ diff --git a/inc/form_validator.class.php b/inc/form_validator.class.php index bed08ab2b..9b5849cea 100644 --- a/inc/form_validator.class.php +++ b/inc/form_validator.class.php @@ -118,6 +118,10 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $for return $itemId; } + public static function countItemsToImport($input) { + return 1; + } + /** * Export in an array all the data of the current instanciated validator * @param boolean $remove_uuid remove the uuid key diff --git a/inc/item_targetticket.class.php b/inc/item_targetticket.class.php index ab596169a..e7cb8050c 100644 --- a/inc/item_targetticket.class.php +++ b/inc/item_targetticket.class.php @@ -154,6 +154,10 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con return $itemId; } + public static function countItemsToImport($input) { + return 1; + } + public function prepareInputForAdd($input) { // generate a unique id if (!isset($input['uuid']) diff --git a/inc/linker.class.php b/inc/linker.class.php index 29df7447c..2aa6718ee 100644 --- a/inc/linker.class.php +++ b/inc/linker.class.php @@ -29,6 +29,8 @@ * --------------------------------------------------------------------- */ +use GlpiPlugin\Formcreator\Exception\ImportFailureException; + if (!defined('GLPI_ROOT')) { die("Sorry. You can't access this file directly"); } @@ -39,6 +41,33 @@ class PluginFormcreatorLinker private $postponed = []; + private $progress = 0; + + private $totalCount = 0; + + public function countItems($input, $itemtype) { + // Get the total count of objects to import, for the progressbar + $this->totalCount += $itemtype::countItemsToImport($input); + } + + public function getProgress() { + return $this->progress; + } + + public function getTotalCount() { + return $this->totalCount; + } + + public function initProgressBar() { + if (!isCommandLine() && !isAPI()) { + echo "
"; + echo ""; + echo "
".__('Importing', 'formcreator')."
"; + Html::createProgressBar(__('Import in progress')); + echo "
\n"; + } + } + /** * Store an object added in the DB * @@ -50,7 +79,14 @@ public function addObject($originalId, PluginFormcreatorExportableInterface $obj if (!isset($this->imported[$object->getType()])) { $this->imported[$object->getType()] = []; } + if (isset($this->imported[$object->getType()][$originalId])) { + throw new ImportFailureException(sprintf('Attempt to create an already created item "%1$s" with original ID "%2$s"', $object->getType(), $originalId)); + } $this->imported[$object->getType()][$originalId] = $object; + $this->progress++; + if (!isCommandLine() && !isAPI()) { + Html::changeProgressBarPosition($this->getProgress(), $this->getTotalCount(), $this->getProgress() . ' / ' . $this->getTotalCount()); + } } /** @@ -139,4 +175,9 @@ public function linkPostponed() { return true; } + + public function reset() { + $this->imported = []; + $this->postponed = []; + } } diff --git a/inc/question.class.php b/inc/question.class.php index 7e60a859d..ac37202f1 100644 --- a/inc/question.class.php +++ b/inc/question.class.php @@ -942,6 +942,15 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con return $itemId; } + public static function countItemsToImport($input) { + // TODO: need improvement to handle parameters + $subItems = [ + '_conditions' => PluginFormcreatorCondition::class, + ]; + + return 1 + self::countChildren($input, $subItems); + } + public function export($remove_uuid = false) { if ($this->isNewItem()) { return false; diff --git a/inc/questiondependency.class.php b/inc/questiondependency.class.php index 0ea34ac4a..fb89fcc7f 100644 --- a/inc/questiondependency.class.php +++ b/inc/questiondependency.class.php @@ -206,6 +206,10 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con return $itemId; } + public static function countItemsToImport($input) { + return 1; + } + public function export($remove_uuid = false) { if ($this->isNewItem()) { return false; diff --git a/inc/questionrange.class.php b/inc/questionrange.class.php index 00f8b241c..2a4a3aa42 100644 --- a/inc/questionrange.class.php +++ b/inc/questionrange.class.php @@ -183,4 +183,9 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con return $itemId; } + + public static function countItemsToImport($input) + { + return 1; + } } diff --git a/inc/questionregex.class.php b/inc/questionregex.class.php index e3a27fdbd..379280615 100644 --- a/inc/questionregex.class.php +++ b/inc/questionregex.class.php @@ -178,4 +178,9 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con return $itemId; } + + public static function countItemsToImport($input) + { + return 1; + } } diff --git a/inc/section.class.php b/inc/section.class.php index d30c1aee6..f4932396c 100644 --- a/inc/section.class.php +++ b/inc/section.class.php @@ -316,6 +316,14 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con return $itemId; } + public static function countItemsToImport($input) { + $subItems = [ + '_questions' => PluginFormcreatorQuestion::class, + '_conditions' => PluginFormcreatorCondition::class, + ]; + return 1 + self::countChildren($input, $subItems); + } + public function export($remove_uuid = false) { if ($this->isNewItem()) { return false; diff --git a/inc/target_actor.class.php b/inc/target_actor.class.php index db1ef6146..c4e748f68 100644 --- a/inc/target_actor.class.php +++ b/inc/target_actor.class.php @@ -181,6 +181,11 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con return $itemId; } + public static function countItemsToImport($input) + { + return 1; + } + /** * Export in an array all the data of the current instanciated actor * @param boolean $remove_uuid remove the uuid key diff --git a/inc/targetchange.class.php b/inc/targetchange.class.php index b810487c8..47da2737b 100644 --- a/inc/targetchange.class.php +++ b/inc/targetchange.class.php @@ -241,6 +241,16 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con return $itemId; } + public static function countItemsToImport($input) { + $subItems = [ + '_actors' => PluginFormcreatorTarget_Actor::class, + '_conditions' => PluginFormcreatorCondition::class, + ]; + + return 1 + self::countChildren($subItems, $input); + } + + public function showForm($ID, $options = []) { if ($ID == 0) { // Not used for now diff --git a/inc/targetticket.class.php b/inc/targetticket.class.php index 7e6c9d0fa..2141254aa 100644 --- a/inc/targetticket.class.php +++ b/inc/targetticket.class.php @@ -1166,6 +1166,16 @@ public static function import(PluginFormcreatorLinker $linker, $input = [], $con return $itemId; } + public static function countItemsToImport($input) { + $subItems = [ + '_actors' => PluginFormcreatorTarget_Actor::class, + '_ticket_relations' => PluginFormcreatorItem_TargetTicket::class, + '_conditions' => PluginFormcreatorCondition::class, + ]; + + return 1 + self::countChildren($subItems, $input); + } + protected function getTaggableFields() { return [ 'target_name',