diff --git a/README_WP.txt b/README_WP.txt
new file mode 100644
index 00000000..6d249b87
--- /dev/null
+++ b/README_WP.txt
@@ -0,0 +1,26 @@
+
+Datainjection changes WP:
+ * cron-schedulable in automatic action, with 2 parameters CSV and Enabled Y/N
+ * added diskinjection and vm injection
+ * additional code in SoftwareVersionInjection and Iten_softwareversioninjection to make it work
+
+PHP files changed
+
+Setup: version, register Diskinjection and VMinjection
+
+Hook: db csvfilename, enable_scheduled_injection
+ Register PluginDatainjectionCron
+ Disable uninstall with return true;
+softwareversionversioninjection: ADD processAfterInsertOrUpdate
+
+model: add getter function getCSVFilename, getEnableScheduledInjection
+ Rawsearchoptions array_merge, cron forms show, WP -- if (!$webservice && !$unique_filename)
+
+Item_SoftwareVersionInjection: added processAfterInsertOrUpdate
+
+New Files:
++++item_diskinjection+++
++++cron.class+++
++++computervirtualmachineinjection+++
+
+
diff --git a/hook.php b/hook.php
index 969fe791..344f3ed1 100644
--- a/hook.php
+++ b/hook.php
@@ -87,6 +87,8 @@ function plugin_datainjection_install() {
`float_format` tinyint NOT NULL DEFAULT '0',
`port_unicity` tinyint NOT NULL DEFAULT '0',
`step` int NOT NULL DEFAULT '0',
+ `csvfilename` VARCHAR(255) NOT NULL DEFAULT '',
+ `enable_scheduled_injection` tinyint NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;";
$DB->queryOrDie($query, $DB->error());
@@ -193,9 +195,25 @@ function plugin_datainjection_install() {
default :
break;
- }
+ }
+
+ // Register crontask DataInjection
- return true;
+ $cron = new CronTask ();
+
+ if (! $cron->getFromDBbyName ( 'PluginDatainjectionCron', 'DataInjection' )) {
+ CronTask::Register ( 'PluginDatainjectionCron', 'DataInjection', DAY_TIMESTAMP, // 86400 sec
+ [ // 'allowmode', 'comment', 'hourmax', 'hourmin', 'logs_lifetime', 'mode', 'param', 'state'
+ 'state' => CronTask::STATE_DISABLE,
+ 'comment' => 'File injection from CSV with defined models',
+ 'mode' => CronTask::MODE_EXTERNAL,
+ 'hourmin' => '3',
+ 'hourmax' => '8'
+ ] );
+ }
+
+
+ return true;
}
@@ -220,6 +238,9 @@ function plugin_datainjection_uninstall() {
}
plugin_init_datainjection();
+
+ CronTask::Unregister('PluginDatainjectionCron');
+
return true;
}
diff --git a/inc/computervirtualmachineinjection.class.php b/inc/computervirtualmachineinjection.class.php
new file mode 100644
index 00000000..6664f4b3
--- /dev/null
+++ b/inc/computervirtualmachineinjection.class.php
@@ -0,0 +1,170 @@
+.
+ * -------------------------------------------------------------------------
+ @author Wuerth Phoenix
+ @copyright Copyright (c) 2010-2013 Datainjection plugin team
+ @copyright Copyright (C) 2017-2022 Wuerth Phoenix, http://www.wuerth-phoenix.com
+ @license GPLv2+
+ http://www.gnu.org/licenses/gpl.txt
+ @link https://forge.indepnet.net/projects/datainjection
+ @link http://www.glpi-project.org/
+ @since 2009
+ ---------------------------------------------------------------------- */
+
+if (!defined('GLPI_ROOT')) {
+ die("Sorry. You can't access directly to this file");
+}
+
+class PluginDatainjectionComputerVirtualMachineInjection extends ComputerVirtualMachine //MOMI from Item_Diskinjection !!
+ implements PluginDatainjectionInjectionInterface {
+
+
+ static function getTable($classname = null) {
+
+ $parenttype = get_parent_class();
+ return $parenttype::getTable();
+ }
+
+
+ function isPrimaryType() {
+ return true;
+ }
+
+
+ function connectedTo() {
+ return array('Computer');
+ }
+
+ /**
+ * @see plugins/datainjection/inc/PluginDatainjectionInjectionInterface::getOptions()
+ **/
+ function getOptions($primary_type='') {
+
+ $tab = Search::getOptions(get_parent_class($this));
+
+ #these have to be added here because they are defined only in rawSearchOptionsToAdd!
+ # -- put id as tab[id] and add linkfield.
+ $tab[161] = [
+ 'table' => 'glpi_virtualmachinestates',
+ 'field' => 'name',
+ 'name' => __('State'),
+ 'forcegroupby' => true,
+ 'massiveaction' => false,
+ 'datatype' => 'dropdown',
+ 'joinparams' => [
+ 'beforejoin' => [
+ 'table' => self::getTable(),
+ 'joinparams' => [
+ 'jointype' => 'child'
+ ]
+ ]
+ ],
+ 'linkfield' => 'virtualmachinestates_id'
+ ];
+
+ $tab[162] = [
+ 'table' => 'glpi_virtualmachinesystems',
+ 'field' => 'name',
+ 'name' => VirtualMachineSystem::getTypeName(1),
+ 'forcegroupby' => true,
+ 'massiveaction' => false,
+ 'datatype' => 'dropdown',
+ 'joinparams' => [
+ 'beforejoin' => [
+ 'table' => self::getTable(),
+ 'joinparams' => [
+ 'jointype' => 'child'
+ ]
+ ]
+ ],
+ 'linkfield' => 'virtualmachinesystems_id'
+ ];
+
+ $tab[163] = [
+ 'table' => 'glpi_virtualmachinetypes',
+ 'field' => 'name',
+ 'name' => VirtualMachineType::getTypeName(1),
+ 'datatype' => 'dropdown',
+ 'forcegroupby' => true,
+ 'massiveaction' => false,
+ 'joinparams' => [
+ 'beforejoin' => [
+ 'table' => self::getTable(),
+ 'joinparams' => [
+ 'jointype' => 'child'
+ ]
+ ]
+ ],
+ 'linkfield' => 'virtualmachinetypes_id'
+ ];
+
+ //Remove some options because some fields cannot be imported
+ $blacklist = array();# = PluginDatainjectionCommonInjectionLib::getBlacklistedOptions(get_parent_class($this));
+ $notimportable = array();
+
+ $options['ignore_fields'] = array_merge($blacklist, $notimportable);
+ $options['displaytype'] = ["dropdown" => [161, 162, 163]];
+
+ return PluginDatainjectionCommonInjectionLib::addToSearchOptions($tab, $options, $this);
+ }
+
+ /**
+ * @param $primary_type
+ * @param $values
+ **/
+ function addSpecificNeededFields($primary_type, $values) {
+
+ $fields = [];
+ if ($primary_type == 'Computer') {
+ $fields['computers_id'] = $values[$primary_type]['id'];
+ }
+ return $fields;
+ }
+
+ /**
+ * @param $fields_toinject array
+ * @param $options array
+ **/
+ function checkPresent($fields_toinject = [], $options = []) {
+ if ($options['itemtype'] != 'ComputerVirtualMachine') {
+ return (" AND `computers_id` = '" . $fields_toinject['Computer']['id'] . "'
+ AND `name` = '" . $fields_toinject['ComputerVirtualMachine']['name'] . "'");
+ }
+ return "";
+ }
+
+ /**
+ * @param $values
+ * @param $add (true by default)
+ * @param $rights array
+ **/
+
+ /**
+ * @see plugins/datainjection/inc/PluginDatainjectionInjectionInterface::addOrUpdateObject()
+ **/
+ function addOrUpdateObject($values = [], $options = []) {
+ //error_log("THIS IS NEVER EXECUTED BECAUSE A COMPUTER IS ADDED, NOT A VM!!" );
+ }
+
+}
diff --git a/inc/cron.class.php b/inc/cron.class.php
new file mode 100644
index 00000000..94bdaaa5
--- /dev/null
+++ b/inc/cron.class.php
@@ -0,0 +1,201 @@
+.
+ * -------------------------------------------------------------------------
+ * @copyright Copyright (C) 2007-2022 by DataInjection plugin team.
+ * @copyright Copyright (C) 2023 Mirko Morandini, Wuerth Phoenix.
+ * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html
+ * @link https://github.com/pluginsGLPI/datainjection
+ * -------------------------------------------------------------------------
+ */
+
+ /*
+ * To add to DB (in hook):
+ ALTER TABLE glpi_plugin_datainjection_models ADD csvfilename VARCHAR(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '';
+ ALTER TABLE glpi_plugin_datainjection_models ADD enable_scheduled_injection tinyint(1) NOT NULL DEFAULT 0;
+ */
+
+if (! defined ( 'GLPI_ROOT' )) {
+ die ( "Sorry. You can't access directly to this file" );
+}
+
+class PluginDatainjectionCron extends CronTask {
+
+ const GLPI_FILEINJECT_DIR = GLPI_VAR_DIR."/_fileinject"; // Path for storage of files to inject
+
+ static public function rawSearchOptionsToAdd($model) {
+ $tab [] = [
+ 'id' => '90',
+ 'table' => $model->getTable(),
+ 'field' => 'csvfilename',
+ 'name' => 'CSV Filename',
+ 'datatype' => 'text'
+ ];
+ $tab [] = [
+ 'id' => '91',
+ 'table' => $model->getTable(),
+ 'field' => 'enable_scheduled_injection',
+ 'name' => 'Enable scheduled injection',
+ 'datatype' => 'bool'
+ ];
+ return $tab;
+ }
+
+ function showAdditionnalForm(PluginDatainjectionModel $model) {
+
+ // $id = $this->getFromDBByModelID($model->fields['id']);
+ // $canedit = $this->can($id, UPDATE);
+
+ echo "
".__('Scheduled import (Automatic Action) options', 'datainjection')." |
";
+
+ echo "";
+ echo "".__('Enable scheduled injection', 'datainjection')." | ";
+ echo "";
+ Dropdown::showYesNo("enable_scheduled_injection", $model->getEnableScheduledInjection());
+ echo " | "."CSV Filename (in ".self::GLPI_FILEINJECT_DIR.")"." | ";
+ echo "";
+ echo "";
+ echo " |
";
+ }
+
+
+ /**
+ * Give AutomaticAction cron information
+ *
+ * @param $name :
+ * automatic action's name
+ *
+ * @return array
+ */
+ static function cronInfo($name) {
+ switch ($name) {
+ case 'cronDataInjection' :
+ return ['description' => __('Scheduled Data Injection', 'datainjection')];
+ #case 'cronDataInjectionAdditional' :
+ # return ['description' => __('Scheduled Data Injection Additional', 'datainjection')];
+ }
+ return [ ];
+ }
+ /**
+ * The Cron Job
+ * @param CronTask $item
+ * @return number
+ */
+ // public static function cronDataInjectionAdditional(CronTask $item) {
+ // return self::cronDataInjection($item);
+ // }
+
+ // New job: searches in all models for an enabled scheduling and the filename saved there.
+ // Models need to be public or by root user!
+ static function cronDataInjection ($task = NULL) {
+ global $DB;
+
+ // To prevent problem of execution time during injection
+ ini_set("max_execution_time", "0");
+
+ #$models = PluginDatainjectionModel::getModels(1, "name", 1, false); // 1 = user root
+ $query = "SELECT `id`, `name`, `is_private`, `entities_id`, `is_recursive`, `itemtype`,`step`, `comment`
+ FROM `glpi_plugin_datainjection_models` WHERE `step` = '".PluginDatainjectionModel::READY_TO_USE_STEP."' AND (";
+ $query .= "(`is_private` = '" . PluginDatainjectionModel::MODEL_PUBLIC."') OR (`users_id` = 1)) ORDER BY `name` DESC";
+ $models = $DB->request($query);
+
+ if (count($models) == 0) {
+ $task->log("No valid public or root models found!");
+ error_log('[DEBUG] no valid models found.');
+ return 0;
+ }
+
+ $returndata = 0; //0: nothing_to_do, >0: success, <0: partial
+ // a loop on all models to get the params and execute each one in sequence:
+ foreach ($models as $singlemodel){
+ $model = new PluginDatainjectionModel();
+ $filename = '';
+ ##$model->can($modelid, READ);
+ $model->getFromDB($singlemodel['id']);
+ if (!$model->getEnableScheduledInjection() || empty($model->getCSVFilename())){
+ # $task->log("Not to schedule....!");
+ continue;
+ }
+ $filename = self::GLPI_FILEINJECT_DIR ."/". $model->getCSVFilename();
+ $modelname = $singlemodel['name'];
+
+ $task->log("Executing scheduled model $modelname on file $filename.");
+ if (!file_exists($filename)) {
+ $task->log("[WARNING] File $filename, defined in $modelname, does not exist. Disable scheduled injection!");
+ error_log ("[WARNING] File $filename, defined in $modelname, does not exist. Disable scheduled injection!");
+ #$returndata = -1;
+ continue;
+ }
+
+ //Read file using automatic encoding detection, and do not delete file once read
+ $options = array('file_encoding' => PluginDatainjectionBackend::ENCODING_AUTO,
+ 'mode' => PluginDatainjectionModel::PROCESS,
+ 'unique_filename' => $filename,
+ 'original_filename' => $filename,
+ 'delete_file' => false);
+ $response = $model->processUploadedFile($options);
+
+ if (! $response) {
+ $task->log ("[ERROR] import errors for file $filename in model $modelname.");
+ error_log ("[ERROR] import errors for file $filename in model $modelname.");
+ $returndata = -1;
+ continue;
+ }
+
+ $additional_infos = [];
+ $engine = new PluginDatainjectionEngine(
+ $model,
+ $additional_infos,
+ $singlemodel['entities_id']
+ );
+ //Remove first line if header is present
+ $first = true;
+ $nb = 0;
+ foreach ($model->injectionData->getData() as $id => $data) {
+ if ($first && $model->getSpecificModel()->isHeaderPresent()) {
+ $first = false;
+ } else {
+ $results[] = $engine->injectLine($data[0], $id);
+ $nb++;
+ }
+ }
+ $model->cleanData();
+
+ if (! is_null ( $task )) {
+ // If the argument $task is a CronTask object, the method must increment the quantity of actions done.
+ $task->addVolume ( 1 );
+ $task->log ( "Import/update of $nb rows for model $modelname successful." );
+ error_log ( "Import/update of $nb rows for model $modelname successful." );
+ if ($returndata == 0)
+ $returndata = 1;
+ }
+ }
+
+ return $returndata;
+
+ }
+
+}
+
+// END
\ No newline at end of file
diff --git a/inc/item_diskinjection.class.php b/inc/item_diskinjection.class.php
new file mode 100644
index 00000000..0df59467
--- /dev/null
+++ b/inc/item_diskinjection.class.php
@@ -0,0 +1,134 @@
+.
+ * -------------------------------------------------------------------------
+ * @author Wuerth Phoenix
+ * @copyright Copyright (C) 2017-2023 Wuerth Phoenix, http://www.wuerth-phoenix.com
+ * @copyright Copyright (C) 2007-2023 by DataInjection plugin team.
+ * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html
+ * @link https://github.com/pluginsGLPI/datainjection
+ * -------------------------------------------------------------------------
+ */
+
+if (!defined('GLPI_ROOT')) {
+ die("Sorry. You can't access directly to this file");
+}
+
+class PluginDatainjectionItem_DiskInjection extends Item_Disk
+ implements PluginDatainjectionInjectionInterface {
+
+
+ static function getTable($classname = null) {
+
+ $parenttype = get_parent_class();
+ return $parenttype::getTable();
+ }
+
+
+ function isPrimaryType() {
+ return true;
+ }
+
+
+ function connectedTo() {
+ return array('Computer');
+ }
+
+ /**
+ * @see plugins/datainjection/inc/PluginDatainjectionInjectionInterface::getOptions()
+ **/
+ function getOptions($primary_type='') {
+
+ $tab = Search::getOptions(get_parent_class($this));
+
+ $tab[101]['table'] = $this->getTable();
+ $tab[101]['field'] = 'totalsize';
+ $tab[101]['linkfield'] = 'totalsize';
+ $tab[101]['name'] = __('Global size');
+ $tab[101]['datatype'] = 'string';
+ $tab[101]['injectable'] = true;
+
+ $tab[102]['table'] = $this->getTable();
+ $tab[102]['field'] = 'freesize';
+ $tab[102]['linkfield'] = 'freesize';
+ $tab[102]['name'] = __('Free size');
+ $tab[102]['datatype'] = 'string';
+ $tab[102]['injectable'] = true;
+
+ //Remove some options because some fields cannot be imported
+ $blacklist = PluginDatainjectionCommonInjectionLib::getBlacklistedOptions(get_parent_class($this));
+ $notimportable = array();
+
+ $options['ignore_fields'] = array_merge($blacklist, $notimportable);
+ $options['displaytype'] = array( "text" => array(101),
+ "text" => array(102));
+
+ return PluginDatainjectionCommonInjectionLib::addToSearchOptions($tab, $options, $this);
+ }
+
+
+ /**
+ * @param $values
+ * @param $add (true by default)
+ * @param $rights array
+ **/
+
+ function processAfterInsertOrUpdate($values, $add=true, $rights=array()) {
+
+ if (isset($values['Computer']['id'])) {
+ $class = get_parent_class($this);
+ $item = new $class();
+
+ $where = [
+ 'itemtype' => 'Computer',
+ 'name' => $values[$class]['name'],
+ 'items_id' => $values['Computer']['id'],
+ ];
+
+ $tmp['items_id'] = $values['Computer']['id'];
+ $tmp['itemtype'] = 'Computer';
+
+ $tmp = $values[$class];
+ unset($tmp['id']);
+
+ if (!countElementsInTable($item->getTable(), $where)) {
+ $item->add($tmp);
+ } else {
+ $datas = getAllDataFromTable($item->getTable(), $where);
+ foreach ($datas as $data) {
+ $tmp['id'] = $data['id'];
+ $item->update($tmp);
+ }
+ }
+ }
+ }
+
+ /**
+ * @see plugins/datainjection/inc/PluginDatainjectionInjectionInterface::addOrUpdateObject()
+ **/
+ function addOrUpdateObject($values = [], $options = []) {
+ //error_log("THIS IS NEVER EXECUTED BECAUSE A COMPUTER IS ADDED, NOT A DISK!!" );
+ }
+
+}
+?>
diff --git a/inc/item_softwareversioninjection.class.php b/inc/item_softwareversioninjection.class.php
index 33f46976..f3ee64ab 100644
--- a/inc/item_softwareversioninjection.class.php
+++ b/inc/item_softwareversioninjection.class.php
@@ -140,5 +140,34 @@ function addSpecificNeededFields($primary_type, $values) {
return $fields;
}
+
+ function processAfterInsertOrUpdate($values, $add=true, $rights=array()) {
+
+ $class = get_parent_class($this);
+ $item = new $class();
+ $where = [
+ 'softwareversions_id'=> $values[$class]['softwareversions_id'],
+ 'itemtype' => $values[$class]['itemtype'],
+ 'items_id' => $values[$class]['items_id'],
+ # I don't search for softwareversions_id, this should be single entry and updated
+ ];
+
+ $tmp = $values[$class];
+ unset($tmp['id']);
+
+ if (!countElementsInTable($item->getTable(), $where)) {
+ $item->add($tmp);
+ } else {
+ $datas = getAllDataFromTable($item->getTable(), $where);
+ foreach ($datas as $data) {
+ //update only first item
+ if (isset($tmp['id'])) {
+ continue;
+ }
+ $tmp['id'] = $data['id'];
+ $item->update($tmp);
+ }
+ }
+ }
}
diff --git a/inc/model.class.php b/inc/model.class.php
index 041ff133..9fef8c77 100644
--- a/inc/model.class.php
+++ b/inc/model.class.php
@@ -225,9 +225,17 @@ function getFloatFormat() {
function getPortUnicity() {
return $this->fields["port_unicity"];
+ }
+
+ function getCSVFilename() {
+ #remove all "../" to avoid excaping from the standard directory
+ return trim(str_replace("../","",$this->fields["csvfilename"]));
}
-
-
+
+ function getEnableScheduledInjection() {
+ return $this->fields["enable_scheduled_injection"];
+ }
+
function getNumberOfMappings() {
if ($this->mappings) {
@@ -482,6 +490,7 @@ function rawSearchOptions() {
'name' => __('Child entities'),
'datatype' => 'bool',
];
+ $tab = array_merge ( $tab, PluginDatainjectionCron::rawSearchOptionsToAdd ($this) );
return $tab;
}
@@ -701,8 +710,11 @@ function showAdvancedForm($ID, $options = []) {
if ($ID > 0) {
$tmp = self::getInstance('csv');
$tmp->showAdditionnalForm($this);
+
+ $tmp = new PluginDatainjectionCron();
+ $tmp->showAdditionnalForm($this);
}
-
+
$this->showFormButtons($options);
return true;
}
@@ -942,8 +954,9 @@ function readUploadedFile($options = []) {
//Get model & model specific fields
$this->loadSpecificModel();
- if (!$webservice) {
- //Get and store uploaded file
+ // load local file by cron
+ if (!$webservice && !$unique_filename) {
+ //Get and store uploaded file
$original_filename = $_FILES['filename']['name'];
$temporary_uploaded_filename = $_FILES["filename"]["tmp_name"];
$unique_filename = tempnam(realpath(PLUGIN_DATAINJECTION_UPLOAD_DIR), "PWS");
@@ -978,7 +991,7 @@ function readUploadedFile($options = []) {
if (!$webservice) {
//Read n line from the CSV file if not webservice
- $injectionData = $backend->read(20);
+ $injectionData = $backend->read(-1);
} else {
//Read the whole file
$injectionData = $backend->read(-1);
diff --git a/inc/softwareversioninjection.class.php b/inc/softwareversioninjection.class.php
index cfe1701e..73c104e7 100644
--- a/inc/softwareversioninjection.class.php
+++ b/inc/softwareversioninjection.class.php
@@ -193,4 +193,33 @@ function checkPresent($fields_toinject = [], $options = []) {
return "";
}
+
+ function processAfterInsertOrUpdate($values, $add=true, $rights=array()) {
+
+ if (isset($values['Software']['id'])) {
+ $class = get_parent_class($this); //"SoftwareVersion"
+ $item = new $class();
+
+ $where = [
+ 'name' => $values[$class]['name'],
+ 'softwares_id' => $values[$class]['items_id'],
+ ];
+
+ $tmp = $values[$class];
+ unset($tmp['id']);
+
+ if (!countElementsInTable($item->getTable(), $where)) {
+ $item->add($tmp);
+ } else {
+ $datas = getAllDataFromTable($item->getTable(), $where);
+ foreach ($datas as $data) {
+ $tmp['id'] = $data['id'];
+ $item->update($tmp);
+ // update only first item (nevertheless there should never be more than one)
+ break;
+ }
+ }
+ }
+ }
+
}
diff --git a/setup.php b/setup.php
index 6f0f6ed6..20531a0d 100644
--- a/setup.php
+++ b/setup.php
@@ -214,7 +214,9 @@ function getTypesToInject() {
'PluginDatainjectionDeviceDriveInjection' => 'datainjection',
'PluginDatainjectionDeviceNetworkCardInjection' => 'datainjection',
'PluginDatainjectionApplianceInjection' => 'datainjection',
- 'PluginDatainjectionCertificateInjection' => 'datainjection'
+ 'PluginDatainjectionCertificateInjection' => 'datainjection',
+ 'PluginDatainjectionItem_DiskInjection' => 'datainjection',
+ 'PluginDatainjectionComputerVirtualMachineInjection' => 'datainjection'
];
//Add plugins
Plugin::doHook('plugin_datainjection_populate');