.
*
* ------------------------------------------------------------------------
*
* This file is used to manage the deploy packages.
*
* ------------------------------------------------------------------------
*
* @package FusionInventory
* @author David Durieux
* @author Alexandre Delaunay
* @copyright Copyright (c) 2010-2016 FusionInventory team
* @license AGPL License 3.0 or (at your option) any later version
* http://www.gnu.org/licenses/agpl-3.0-standalone.html
* @link http://www.fusioninventory.org/
* @link https://github.com/fusioninventory/fusioninventory-for-glpi
*
*/
if (!defined('GLPI_ROOT')) {
die("Sorry. You can't access directly to this file");
}
/**
* Manage the deploy packages.
*/
class PluginFusioninventoryDeployPackage extends CommonDBTM {
/**
* Initialize the tasks running with this package (updated with overrided getFromDB method)
*
* @var array
*/
public $running_tasks = [];
/**
* The right name for this class
*
* @var string
*/
static $rightname = 'plugin_fusioninventory_package';
/**
* Initialize the users visibility of package for self-service deploy
*
* @var array
*/
protected $users = [];
/**
* Initialize the groups visibility of package for self-service deploy
*
* @var array
*/
protected $groups = [];
/**
* Initialize the profiles visibility of package for self-service deploy
*
* @var array
*/
protected $profiles = [];
/**
* Initialize the entities visibility of package for self-service deploy
*
* @var array
*/
protected $entities = [];
/**
* Get name of this type by language of the user connected
*
* @param integer $nb number of elements
* @return string name of this type
*/
static function getTypeName($nb = 0) {
return __('Package', 'fusioninventory');
}
function getFromDB($ID) {
$found = parent::getFromDB($ID);
if ($found) {
// Get all tasks runnning
$this->running_tasks =
PluginFusioninventoryTask::getItemsFromDB(
[
'is_active' => true,
'is_running' => true,
'targets' => [__CLASS__ => $this->fields['id']],
'by_entities' => false,
]
);
}
return $found;
}
/**
* Have I the right to "update" the object content (package actions)
*
* Also call canUpdateItem()
*
* @return booleen
**/
function canUpdateContent() {
// check if a task is currenlty runnning with this package
if (count($this->running_tasks)) {
return false;
}
return parent::canUpdateItem();
}
/**
* Get the massive actions for this object
*
* @param object|null $checkitem
* @return array list of actions
*/
function getSpecificMassiveActions($checkitem = null) {
$actions = [];
if (strstr($_SERVER["HTTP_REFERER"], 'deploypackage.import.php')) {
$actions[__CLASS__.MassiveAction::CLASS_ACTION_SEPARATOR.'import'] = __('Import', 'fusioninventory');
} else {
$actions[__CLASS__.MassiveAction::CLASS_ACTION_SEPARATOR.'transfert'] = __('Transfer');
$actions[__CLASS__.MassiveAction::CLASS_ACTION_SEPARATOR.'export'] = __('Export', 'fusioninventory');
$actions[__CLASS__.MassiveAction::CLASS_ACTION_SEPARATOR.'duplicate'] = _sx('button', 'Duplicate');
}
return $actions;
}
/**
* Define standard massiveaction actions to deny
*
* @return array list of actions to deny
*/
function getForbiddenStandardMassiveAction() {
$forbidden = parent::getForbiddenStandardMassiveAction();
if (strstr($_SERVER["HTTP_REFERER"], 'deploypackage.import.php')) {
$forbidden[] = 'update';
$forbidden[] = 'add';
$forbidden[] = 'delete';
$forbidden[] = 'purge';
}
return $forbidden;
}
/**
* Display form related to the massive action selected
*
* @param object $ma MassiveAction instance
* @return boolean
*/
static function showMassiveActionsSubForm(MassiveAction $ma) {
switch ($ma->getAction()) {
case 'transfert':
Dropdown::show('Entity');
echo "
".Html::submit(__('Post'),
['name' => 'massiveaction']);
return true;
case 'duplicate':
echo Html::submit(_x('button', 'Post'), ['name' => 'massiveaction']);
return true;
}
return parent::showMassiveActionsSubForm($ma);
}
/**
* Execution code for massive action
*
* @param object $ma MassiveAction instance
* @param object $item item on which execute the code
* @param array $ids list of ID on which execute the code
*/
static function processMassiveActionsForOneItemtype(MassiveAction $ma, CommonDBTM $item, array $ids) {
switch ($ma->getAction()) {
case 'export' :
foreach ($ids as $key) {
if ($item->can($key, UPDATE)) {
$item->exportPackage($key);
$ma->itemDone($item->getType(), $key, MassiveAction::ACTION_OK);
}
}
break;
case 'transfert' :
$pfDeployPackage = new PluginFusioninventoryDeployPackage();
foreach ($ids as $key) {
if ($pfDeployPackage->getFromDB($key)) {
$input = [];
$input['id'] = $key;
$input['entities_id'] = $ma->POST['entities_id'];
$pfDeployPackage->update($input);
}
}
break;
case 'import' :
foreach ($ids as $key) {
$item->importPackage($key);
$ma->itemDone($item->getType(), $key, MassiveAction::ACTION_OK);
}
break;
case 'duplicate':
$pfPackage = new self();
foreach ($ids as $key) {
if ($pfPackage->getFromDB($key)) {
if ($pfPackage->duplicate($pfPackage->getID())) {
//set action massive ok for this item
$ma->itemDone($item->getType(), $key, MassiveAction::ACTION_OK);
} else {
// KO
$ma->itemDone($item->getType(), $key, MassiveAction::ACTION_KO);
}
}
}
break;
}
}
/**
* Define error message if package used in task. This will prevent edit the
* package
*
* @return string
*/
function getEditErrorMessage() {
$error_message = "";
if (count($this->running_tasks) > 0) {
// Display error message
$error_message .= "
";
$error_message .= "";
$error_message .= "
".__("Modification Denied", 'fusioninventory')."
\n";
$error_message .= "
".
_n(
"The following task is running with this package",
"The following tasks are running with this package",
count($this->running_tasks), 'fusioninventory'
).
"
";
// Display an error if the package modification is not possible
$canedit = $this->canUpdateContent();
$error_msg = $this->getEditErrorMessage();
if (!empty($error_msg)) {
echo "
$error_msg
";
}
// Display the lists of each subtypes of a package
foreach ($subtypes as $subtype => $label) {
echo "
";
/**
* File's form must be encoded as multipart/form-data
**/
$multipart = "";
if ($subtype == "file") {
$multipart = "enctype='multipart/form-data'";
}
echo "
";
echo "
";
/**
* Display subtype form
**/
echo "
";
echo "
";
}
echo "
";
}
/**
* Manage + button (audits, files, actions)
*
* @global array $CFG_GLPI
* @param integer $id id of the package
* @param string $subtype name of subtype (audits, files, actions)
* @param string $rand random string for js to prevent collisions
*/
function plusButtonSubtype($id, $subtype, $rand) {
global $CFG_GLPI;
if ($this->can($id, UPDATE)) {
echo " ";
echo " ";
}
}
/**
* Plus button used to add an element
*
* @global array $CFG_GLPI
* @param string $dom_id
* @param boolean $clone
*/
static function plusButton($dom_id, $clone = false) {
global $CFG_GLPI;
echo " ";
echo " ";
}
/**
* When user is in DEBUG mode, we display the json
*
* @global array $CFG_GLPI
*/
function showDebug() {
global $CFG_GLPI;
echo "
";
return true;
}
/**
* Fill internal variable with visibility elements when load package
* information from database
*/
function post_getFromDB() {
// Users
$this->users = PluginFusioninventoryDeployPackage_User::getUsers($this->fields['id']);
// Entities
$this->entities = PluginFusioninventoryDeployPackage_Entity::getEntities($this->fields['id']);
// Group / entities
$this->groups = PluginFusioninventoryDeployPackage_Group::getGroups($this->fields['id']);
// Profile / entities
$this->profiles = PluginFusioninventoryDeployPackage_Profile::getProfiles($this->fields['id']);
}
/**
* Get all available states for a package
* @return an array of states and their labels
*/
static function getPackageDeploymentStates() {
return [
'agents_notdone' => __('Not done yet', 'fusioninventory'),
'agents_error' => __('In error', 'fusioninventory'),
'agents_success' => __('Successful', 'fusioninventory'),
'agents_running' => __('Running', 'fusioninventory'),
'agents_prepared' => __('Prepared', 'fusioninventory'),
'agents_cancelled' => __('Cancelled', 'fusioninventory') ];
}
/**
* Get a label for a state
* @param state the state
* @return the label associated to a state
*/
static function getDeploymentLabelForAState($state) {
$states = self::getPackageDeploymentStates();
if (isset($states[$state])) {
return $states[$state];
} else {
return '';
}
}
/**
* Display a form with a list of packages and their state, that a user
* has request to install on it's computer
*
* @param integer $users_id id of the user
* @param $item source item (maybe a User or a computer)
*/
function showPackageForMe($users_id, $item = false) {
global $CFG_GLPI;
$computer = new Computer();
$self_service = !($_SESSION['glpiactiveprofile']['interface'] == 'central');
if (!$self_service) {
$computers_id = false;
if ($item && $item instanceof Computer) {
$computers_id = $item->getID();
}
$my_packages = $this->getPackageForMe(false, $computers_id);
} else {
$my_packages = $this->getPackageForMe($users_id);
}
// check current interface
$is_tech = isset($_SESSION['glpiactiveprofile']['interface'])
&& $_SESSION['glpiactiveprofile']['interface'] == "central";
// retrieve state name
$joblogs_labels = PluginFusioninventoryTaskjoblog::dropdownStateValues();
// Display for each computer, list of packages you can deploy
$url = Plugin::getWebDir('fusioninventory');
echo "
";
if ($is_tech) {
// display also last log (folded)
echo "
";
echo "
";
// if job is in error, suggest restart
if (in_array($package_info['last_taskjobstate']['state'],
["agents_error", "agents_success"])) {
echo "";
}
// if job has not started, user can cancel it
if ($package_info['last_taskjobstate']['state'] == "agents_prepared") {
echo "";
}
// permits to "soft" refresh
echo "";
echo "
"; // .buttons
// log list
echo "
";
foreach ($package_info['last_taskjobstate']['logs'] as $log) {
echo "
";
echo "
".$log['log.f_date']."
";
echo "
".$joblogs_labels[$log['log.state']]."
";
echo "
".$log['log.comment']."
";
echo "
";
}
echo "
"; // .runs
echo '
'; // .agent_block
}
echo '
'; // .counter_block
// js controls (toggle, restart)
echo Html::scriptBlock("$(function() {
var logstatuses_names = ".json_encode($joblogs_labels).";
$('#toggle_run_$taskjob_id').click(function(event){
event.preventDefault();
$('#run_$taskjob_id').toggle();
$(this).toggleClass('expand')
.parent('td')
.nextAll('td').toggle();
});
$('#cancel_run_$taskjob_id').click(function(event){
event.preventDefault();
$.ajax({
url: '".$url."/ajax/cancel_job.php',
data: {
'jobstate_id': ".$package_info['last_taskjobstate']['id'].",
'agent_id': ".$package_info['agent_id']."
},
complete: function() {
document.location.reload();
}
});
});
$('#restart_run_$taskjob_id').click(function(event){
event.preventDefault();
$.ajax({
url: '".$url."/ajax/restart_job.php',
data: {
'jobstate_id': ".$package_info['last_taskjobstate']['id'].",
'agent_id': ".$package_info['agent_id']."
},
complete: function() {
document.location.reload();
}
});
});
$('#refresh_run_$taskjob_id i').click(function() {
var fa = $(this);
fa.addClass('fa-spin fa-spinner')
.removeClass('fa-refresh');
$.ajax({
url: '".$url."/ajax/jobstates_logs.php',
data: {
'id': ".$package_info['last_taskjobstate']['id'].",
'last_date': '2999-01-01 00:00:00' // force a future date
},
success: function(data){
// no data -> reload tab
if (typeof data.logs == 'undefined') {
reloadTab();
return;
}
if (data.logs.length) {
// remove old data
$('#runs_$taskjob_id').empty();
$.each(data.logs, function( index, log ) {
$('#runs_$taskjob_id').append(
'
";
echo Html::submit(__('Prepare for install', 'fusioninventory'),
['name' => 'prepareinstall']);
echo " ";
if (!$self_service) {
$options = ['local' => __("I'm on this computer: local wakeup", 'fusioninventory'),
'remote' => __("I'm not on this computer: wakeup from the server", 'fusioninventory'),
'none' => __("Don't wakeup", 'fusioninventory')
];
Dropdown::showFromArray('wakeup_type', $options,
['value' => 'remote']);
} else {
echo Html::hidden('wakeup_type', ['value' => 'local']);
}
echo Html::hidden('self_service', ['value' => $self_service]);
echo "
";
echo "
";
} else {
echo "
";
echo "
";
echo __('No packages available to install', 'fusioninventory');
echo "
";
echo "
";
}
}
echo "
"; // .tab_cadre_fixe
Html::closeForm();
}
/**
* Check if an agent have deploy feature enabled
* @since 9.2
*
* @param integer $computers_id the ID of the computer to check
* @return boolean true if deploy is enabled for the agent
*/
static function isDeployEnabled($computers_id) {
$pfAgent = new PluginFusioninventoryAgent();
//If the agent associated with the computer has not the
//deploy feature enabled, do not propose to deploy packages on
if (!$pfAgent->getAgentWithComputerid($computers_id)) {
return false;
}
$pfAgentModule = new PluginFusioninventoryAgentmodule();
if ($pfAgentModule->isAgentCanDo('deploy', $pfAgent->getID())) {
return true;
} else {
return false;
}
}
/**
* Get deploy packages available to install on user computer(s) and for
* packages requested the state of deploy
*
* @param integer $users_id id of the user
*/
function getPackageForMe($users_id, $computers_id = false) {
$computer = new Computer();
$pfDeployGroup = new PluginFusioninventoryDeployGroup();
$my_packages = []; //Store all installable packages
$query = [];
if ($users_id) {
$query += ['users_id' => $users_id];
}
if ($computers_id) {
$query += ['id' => $computers_id];
}
$query += ['entities_id' => $_SESSION['glpiactiveentities']];
//Get all computers of the user
$mycomputers = $computer->find($query);
$pfAgent = new PluginFusioninventoryAgent();
foreach ($mycomputers as $mycomputers_id => $data) {
$my_packages[$mycomputers_id] = [];
}
//Get packages used for the user or a specific computer
$packages_used = $this->getMyDepoyPackages($my_packages, $users_id);
//Get packages that a the user can deploy
$packages = $this->canUserDeploySelf();
if ($packages) {
//Browse all packages that the user can install
foreach ($packages as $package) {
//Get computers that can be targeted for this package installation
$computers = $pfDeployGroup->getTargetsForGroup($package['plugin_fusioninventory_deploygroups_id']);
//Browse all computers that are target by a a package installation
foreach ($mycomputers as $comp_id => $data) {
//If we only want packages for one computer
//check if it's the computer we look for
if ($computers_id && $comp_id != $computers_id) {
continue;
}
//If the agent associated with the computer has not the
//deploy feature enabled, do not propose to deploy packages on it
if (!self::isDeployEnabled($comp_id)) {
continue;
}
//Get computers that can be targeted for this package installation
//Check if the package belong to one of the entity that
//are currenlty visible
//The package is recursive, and visible in computer's entity
if (Session::isMultiEntitiesMode()) {
if (!$package['is_recursive']
&& $package['entities_id'] != $data['entities_id']) {
continue;
} else if ($package['is_recursive']
&& $package['entities_id'] != $data['entities_id']
&& !in_array($package['entities_id'],
getAncestorsOf('glpi_entities', $data['entities_id']))) {
//The package is not recursive, and invisible in the computer's entity
continue;
}
}
//Does the computer belongs to the group
//associated with the package ?
if (isset($computers[$comp_id])) {
$my_packages[$comp_id][$package['id']]
= ['name' => $package['name'],
'agent_id' => $pfAgent->getId()];
//The package has already been deployed or requested to deploy
if (isset($packages_used[$comp_id][$package['id']])) {
$taskjobs_id = $packages_used[$comp_id][$package['id']];
$my_packages[$comp_id][$package['id']]['taskjobs_id'] = $taskjobs_id;
$last_job_state = $this->getMyDepoyPackagesState($comp_id, $taskjobs_id);
if ($last_job_state) {
$my_packages[$comp_id][$package['id']]['last_taskjobstate']
= $last_job_state;
}
}
}
}
}
}
return $my_packages;
}
/**
* Add the package in task or use existant task and add the computer in
* taskjob
*
* @global object $DB
* @param integer $computers_id id of the computer where depoy package
* @param integer $packages_id id of the package to install in computer
* @param integer $users_id id of the user have requested the installation
*/
function deployToComputer($computers_id, $packages_id, $users_id) {
global $DB;
$pfTask = new PluginFusioninventoryTask();
$pfTaskJob = new PluginFusioninventoryTaskJob();
$computer = new Computer();
$computer->getFromDB($computers_id);
//Get jobs for a package on a computer
$query = "SELECT `job`.*
FROM `glpi_plugin_fusioninventory_taskjobs` AS job"
. " LEFT JOIN `glpi_plugin_fusioninventory_tasks` AS task"
. " ON `task`.`id` = `job`.`plugin_fusioninventory_tasks_id`"
. " WHERE `job`.`targets`='[{\"PluginFusioninventoryDeployPackage\":\"".$packages_id."\"}]'"
. " AND `task`.`is_active`='1'"
. " AND `task`.`is_deploy_on_demand`='1'"
. " AND `task`.`entities_id`='".$computer->fields['entities_id']."'"
. " AND `task`.`reprepare_if_successful`='0'"
." AND `job`.`method`='deployinstall'"
. " LIMIT 1";
$iterator = $DB->request($query);
// case 1: if exist, we add computer in actors of the taskjob
if ($iterator->numrows() == 1) {
foreach ($iterator as $data) {
//Get current list of actors
$actors = importArrayFromDB($data['actors']);
//Add a new actor : the computer that is being processed
$actors[] = ['Computer' => $computers_id];
//Get end user computers
$enduser = importArrayFromDB($data['enduser']);
if (isset($enduser[$users_id])) {
if (!in_array($computers_id, $enduser[$users_id])) {
$enduser[$users_id][] = $computers_id;
}
} else {
$enduser[$users_id] = [$computers_id];
}
$input = [
'id' => $data['id'],
'actors' => exportArrayToDB($actors),
'enduser' => exportArrayToDB($enduser)
];
//Update the job with the new actor
$pfTaskJob->update($input);
$tasks_id = $data['plugin_fusioninventory_tasks_id'];
}
} else {
// case 2: if not exist, create a new task + taskjob
$this->getFromDB($packages_id);
//Add the new task
$input = [
'name' => '[deploy on demand] '.$this->fields['name'],
'entities_id' => $computer->fields['entities_id'],
'reprepare_if_successful' => 0,
'is_deploy_on_demand' => 1,
'is_active' => 1,
];
$tasks_id = $pfTask->add($input);
//Add a new job for the newly created task
//and enable it
$input = [
'plugin_fusioninventory_tasks_id' => $tasks_id,
'entities_id' => $computer->fields['entities_id'],
'name' => 'deploy',
'method' => 'deployinstall',
'targets' => '[{"PluginFusioninventoryDeployPackage":"'.$packages_id.'"}]',
'actors' => exportArrayToDB([['Computer' => $computers_id]]),
'enduser' => exportArrayToDB([$users_id => [$computers_id]]),
];
$pfTaskJob->add($input);
}
//Prepare the task (and only this one)
$pfTask->prepareTaskjobs(['deployinstall'], $tasks_id);
}
/**
* Get all packages that a user has requested to install
* on one of it's computer
*
* @global object $DB
* @param array $computers_packages
* @param integer $users_id
* @return array
*/
function getMyDepoyPackages($computers_packages, $users_id = false) {
global $DB;
// Get packages yet deployed by enduser
$packages_used = [];
foreach ($computers_packages as $computers_id => $data) {
$packages_used[$computers_id] = [];
}
if ($users_id) {
$where = "`enduser` IS NOT NULL";
} else {
$where = "1 ";
}
$sql = "SELECT `job`.*
FROM `glpi_plugin_fusioninventory_taskjobs` AS job
LEFT JOIN `glpi_plugin_fusioninventory_tasks` AS task
ON `task`.`id` = `job`.`plugin_fusioninventory_tasks_id`
WHERE $where
AND `task`.`is_deploy_on_demand`='1'
AND `task`.`is_active`='1'
AND `task`.`entities_id`
IN (".$_SESSION['glpiactiveentities_string'].")";
foreach ($DB->request($sql) as $data) {
//Only look for deploy tasks
if ($data['method'] != 'deployinstall') {
continue;
}
//Look for all deploy on demand packages for a user
if ($users_id) {
$enduser = importArrayFromDB($data['enduser']);
if (isset($enduser[$users_id])) {
$targets = importArrayFromDB($data['targets']);
foreach ($enduser[$users_id] as $computers_id) {
$packages_used[$computers_id][$targets[0]['PluginFusioninventoryDeployPackage']] = $data['id'];
}
}
//Look for all deploy on demand package for a computer
} else {
$targets = importArrayFromDB($data['targets']);
$actors = importArrayFromDB($data['actors']);
foreach ($actors as $actor) {
foreach ($actor as $itemtype => $items_id) {
if ($itemtype == 'Computer' && $items_id == $computers_id) {
$packages_used[$computers_id][$targets[0]['PluginFusioninventoryDeployPackage']] = $data['id'];
}
}
}
}
}
return $packages_used;
}
/**
* Get the state of the package I have requeted to install
*
* @param integer $computers_id id of the computer
* @param integer $taskjobs_id id of the taskjob (where order defined)
* @param string $packages_name name of the package
*/
function getMyDepoyPackagesState($computers_id, $taskjobs_id) {
$pfTaskJobState = new PluginFusioninventoryTaskjobstate();
$pfAgent = new PluginFusioninventoryAgent();
// Get a taskjobstate by giving a taskjobID and a computer ID
$agents_id = $pfAgent->getAgentWithComputerid($computers_id);
$last_job_state = [];
$taskjobstates = current($pfTaskJobState->find(
['plugin_fusioninventory_taskjobs_id' => $taskjobs_id,
'plugin_fusioninventory_agents_id' => $agents_id], ['id DESC'], 1));
if ($taskjobstates) {
$state = '';
switch ($taskjobstates['state']) {
case PluginFusioninventoryTaskjobstate::CANCELLED :
$state = 'agents_cancelled';
break;
case PluginFusioninventoryTaskjobstate::PREPARED :
$state = 'agents_prepared';
break;
case PluginFusioninventoryTaskjobstate::SERVER_HAS_SENT_DATA :
case PluginFusioninventoryTaskjobstate::AGENT_HAS_SENT_DATA :
$state = 'agents_running';
break;
case PluginFusioninventoryTaskjobstate::IN_ERROR :
$state = 'agents_error';
break;
case PluginFusioninventoryTaskjobstate::FINISHED :
$state = 'agents_success';
break;
}
$logs = $pfTaskJobState->getLogs($taskjobstates['id'],
$_SESSION['glpi_currenttime']);
$last_job_state['id'] = $taskjobstates['id'];
$last_job_state['state'] = $state;
$last_job_state['date'] = $logs['logs'][0]['log.date'];
$last_job_state['logs'] = $logs['logs'];
}
return $last_job_state;
}
/**
* Check I have rights to deploy packages
*
* @global object $DB
* @return false|array
*/
function canUserDeploySelf() {
global $DB;
$table = "glpi_plugin_fusioninventory_deploypackages";
$where = " WHERE `".$table."`.`plugin_fusioninventory_deploygroups_id` > 0 "
. " AND (";
//Include groups
if (!empty($_SESSION['glpigroups'])) {
$where .= " `glpi_plugin_fusioninventory_deploypackages_groups`.`groups_id`
IN ('".implode("', '", $_SESSION['glpigroups'])."') OR ";
}
//Include entity
$where.= getEntitiesRestrictRequest('', 'glpi_plugin_fusioninventory_deploypackages_entities',
'entities_id', $_SESSION['glpiactive_entity'], true);
//Include user
$where .= " OR `glpi_plugin_fusioninventory_deploypackages_users`.`users_id`='".$_SESSION['glpiID']."' OR ";
//Include profile
$where .= " `glpi_plugin_fusioninventory_deploypackages_profiles`.`profiles_id`='".$_SESSION['glpiactiveprofile']['id']."' ";
$where .= " )";
$query = "SELECT DISTINCT `".$table."`.*
FROM `$table`
LEFT JOIN `glpi_plugin_fusioninventory_deploypackages_groups`
ON (`glpi_plugin_fusioninventory_deploypackages_groups`.`plugin_fusioninventory_deploypackages_id` = `$table`.`id`)
LEFT JOIN `glpi_plugin_fusioninventory_deploypackages_entities`
ON (`glpi_plugin_fusioninventory_deploypackages_entities`.`plugin_fusioninventory_deploypackages_id` = `$table`.`id`)
LEFT JOIN `glpi_plugin_fusioninventory_deploypackages_users`
ON (`glpi_plugin_fusioninventory_deploypackages_users`.`plugin_fusioninventory_deploypackages_id` = `$table`.`id`)
LEFT JOIN `glpi_plugin_fusioninventory_deploypackages_profiles`
ON (`glpi_plugin_fusioninventory_deploypackages_profiles`.`plugin_fusioninventory_deploypackages_id` = `$table`.`id`)
$where";
$result = $DB->query($query);
$a_packages = [];
if ($DB->numrows($result) > 0) {
while ($data = $DB->fetchAssoc($result)) {
$a_packages[$data['id']] = $data;
}
return $a_packages;
}
return false;
}
/**
* Duplicate a deploy package
* @param $deploypackages_id the ID of the package to duplicate
* @return duplication process status
*/
public function duplicate($deploypackages_id) {
if (!$this->getFromDB($deploypackages_id)) {
return false;
}
$result = true;
$input = $this->fields;
$input['name'] = sprintf(__('Copy of %s'),
$this->fields['name']);
unset($input['id']);
$input = Toolbox::addslashes_deep($input);
if (!$this->add($input)) {
$result = false;
}
return $result;
}
/**
* Append needed informations to the json job for an agent
* @since 9.2
* @param $agent_task_version the version of the agent's deploy task
* @param $job the job as an array
* @return array the job plus new needed fields
*/
function buildJson($agent_task_version, $job) {
//If task doesn't support checks skip, info, warning,
//send an ignore instead
//tasks version needs to be at least 2.2
$is_old_agent = version_compare($agent_task_version, '2.2', 'lt');
if ($is_old_agent && isset($job['job']['checks'])) {
foreach ($job['job']['checks'] as $key => $value) {
if (in_array($value['return'], ['skip', 'info', 'warning'])) {
$job['job']['checks'][$key]['return'] = 'ignore';
}
}
}
//No need to perform further test if the agent doesn't support
//user interactions
if ($is_old_agent) {
return $job;
}
$do_interaction = true;
$jobstate = new PluginFusioninventoryTaskjobstate();
//Job has reached the maximum number of retries, do not interact with the user
//and execute the job
$jobstate->getFromDBByUniqID($job['job']['uuid']);
if (isset($jobstate->fields['nb_retry'])
&& $jobstate->fields['max_retry'] > 0) {
if ($jobstate->fields['nb_retry'] >= $jobstate->fields['max_retry']) {
$do_interaction = false;
}
}
//If the number of retries has been met,
//remove all userinteractions directives
if (!$do_interaction) {
unset($job['job']['userinteractions']);
} else if (isset($job['job']['userinteractions'])) {
$template = new PluginFusioninventoryDeployUserinteractionTemplate();
foreach ($job['job']['userinteractions'] as $key => $value) {
if (isset($value['template']) && $value['template']) {
if ($template->getFromDB($value['template'])) {
$job['job']['userinteractions'][$key]
= $template->addJsonFieldsToArray($job['job']['userinteractions'][$key]);
unset ($job['job']['userinteractions'][$key]['template']);
$job['job']['userinteractions'][$key]['text']
= str_replace(PluginFusioninventoryDeployUserinteraction::RN_TRANSFORMATION, "\r\n",
$job['job']['userinteractions'][$key]['text']);
}
}
}
}
return $job;
}
/**
* Transform \r\n in an userinteraction text
* @since 9.2
* @param array $params the input parameters
* @return array $params input parameters with text modified
*/
public function escapeText($params) {
//Hack to keep \r\n in the user interaction text
//before going to stripslashes_deep
if (isset($params['text'])) {
$params['text']
= str_replace('\r\n',
PluginFusioninventoryDeployUserinteraction::RN_TRANSFORMATION,
$params['text']);
}
return $params;
}
}