2116 lines
72 KiB
PHP
2116 lines
72 KiB
PHP
<?php
|
|
|
|
/**
|
|
* FusionInventory
|
|
*
|
|
* Copyright (C) 2010-2016 by the FusionInventory Development Team.
|
|
*
|
|
* http://www.fusioninventory.org/
|
|
* https://github.com/fusioninventory/fusioninventory-for-glpi
|
|
* http://forge.fusioninventory.org/
|
|
*
|
|
* ------------------------------------------------------------------------
|
|
*
|
|
* LICENSE
|
|
*
|
|
* This file is part of FusionInventory project.
|
|
*
|
|
* FusionInventory is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* FusionInventory is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with FusionInventory. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* ------------------------------------------------------------------------
|
|
*
|
|
* 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 "<br><br>".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 .= "<div class='warning'>";
|
|
$error_message .= "<i class='fa fa-exclamation-triangle fa-3x'></i>";
|
|
$error_message .= "<h3>".__("Modification Denied", 'fusioninventory')."</h3>\n";
|
|
$error_message .= "<h4>".
|
|
_n(
|
|
"The following task is running with this package",
|
|
"The following tasks are running with this package",
|
|
count($this->running_tasks), 'fusioninventory'
|
|
).
|
|
"</h4>\n";
|
|
|
|
foreach ($this->running_tasks as $task) {
|
|
$taskurl =
|
|
PluginFusioninventoryTask::getFormURLWithID($task['task']['id'], true);
|
|
$error_message .= "<a href='$taskurl'>".$task['task']['name']."</a>, ";
|
|
}
|
|
$error_message .= "</div>";
|
|
}
|
|
return $error_message;
|
|
}
|
|
|
|
|
|
/**
|
|
* Prepare data before add to database
|
|
*
|
|
* @param array $input
|
|
* @return array
|
|
*/
|
|
function prepareInputForAdd($input) {
|
|
if (!isset($input['json'])) {
|
|
$input['json'] = json_encode([
|
|
'jobs' => [
|
|
'checks' => [],
|
|
'associatedFiles' => [],
|
|
'actions' => [],
|
|
'userinteractions' => []
|
|
],
|
|
'associatedFiles' => []]);
|
|
}
|
|
|
|
return parent::prepareInputForAdd($input);
|
|
}
|
|
|
|
|
|
/**
|
|
* Get search function for the class
|
|
*
|
|
* @return array
|
|
*/
|
|
function rawSearchOptions() {
|
|
$tab = [];
|
|
$tab[] = [
|
|
'id' => 'common',
|
|
'name' => __('Characteristics')
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '1',
|
|
'table' => $this->getTable(),
|
|
'field' => 'name',
|
|
'name' => __('Name'),
|
|
'datatype' => 'itemlink',
|
|
'itemlink_link' => $this->getType(),
|
|
'autocomplete' => true,
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '2',
|
|
'table' => $this->getTable(),
|
|
'field' => 'id',
|
|
'name' => __('ID'),
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '16',
|
|
'table' => $this->getTable(),
|
|
'field' => 'comment',
|
|
'name' => __('Comments'),
|
|
'datatype' => 'text',
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '19',
|
|
'table' => $this->getTable(),
|
|
'field' => 'date_mod',
|
|
'name' => __('Last update'),
|
|
'datatype' => 'datetime',
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '80',
|
|
'table' => 'glpi_entities',
|
|
'field' => 'completename',
|
|
'name' => Entity::getTypeName(1),
|
|
'datatype' => 'dropdown',
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '86',
|
|
'table' => $this->getTable(),
|
|
'field' => 'is_recursive',
|
|
'name' => __('Child entities'),
|
|
'datatype' => 'bool',
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '20',
|
|
'table' => 'glpi_plugin_fusioninventory_deploygroups',
|
|
'field' => 'name',
|
|
'name' => __('Enable deploy on demand for the following group', 'fusioninventory'),
|
|
'datatype' => 'dropdown',
|
|
];
|
|
|
|
return $tab;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get all packages in json format
|
|
*
|
|
* @return json
|
|
*/
|
|
function getAllDatas() {
|
|
global $DB;
|
|
|
|
$sql = " SELECT id, name
|
|
FROM `".$this->getTable()."`
|
|
ORDER BY name";
|
|
$res = $DB->query($sql);
|
|
$nb = $DB->numrows($res);
|
|
$json = [];
|
|
$i = 0;
|
|
while ($row = $DB->fetchAssoc($res)) {
|
|
$json['packages'][$i]['package_id'] = $row['id'];
|
|
$json['packages'][$i]['package_name'] = $row['name'];
|
|
$i++;
|
|
}
|
|
$json['results'] = $nb;
|
|
return json_encode($json);
|
|
}
|
|
|
|
|
|
/**
|
|
* Clean orders after delete the package
|
|
*
|
|
*/
|
|
function post_deleteFromDB() {
|
|
$pfDeployFile = new PluginFusioninventoryDeployFile();
|
|
// remove file in repo
|
|
$json = json_decode($this->fields['json'], true);
|
|
if (is_null($json)) {
|
|
return;
|
|
}
|
|
foreach ($json['associatedFiles'] as $sha512 => $file) {
|
|
$pfDeployFile->removeFileInRepo($sha512);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Display the menu / list of packages
|
|
*
|
|
* @param array $options
|
|
*/
|
|
function showMenu($options = []) {
|
|
|
|
$this->displaylist = false;
|
|
$this->fields['id'] = -1;
|
|
$this->showList();
|
|
}
|
|
|
|
|
|
/**
|
|
* Display list of packages
|
|
*/
|
|
function showList() {
|
|
Search::show('PluginFusioninventoryDeployPackage');
|
|
}
|
|
|
|
|
|
/**
|
|
* Define tabs to display on form page
|
|
*
|
|
* @param array $options
|
|
* @return array containing the tabs name
|
|
*/
|
|
function defineTabs($options = []) {
|
|
$ong = [];
|
|
$this->addDefaultFormTab($ong);
|
|
$this->addStandardTab(__CLASS__, $ong, $options);
|
|
$ong['no_all_tab'] = true;
|
|
return $ong;
|
|
}
|
|
|
|
|
|
/**
|
|
* Display form
|
|
*
|
|
* @param integer $ID
|
|
* @param array $options
|
|
* @return true
|
|
*/
|
|
function showForm($ID, $options = []) {
|
|
$this->initForm($ID, $options);
|
|
$this->showFormHeader($options);
|
|
//Add redips_clone element before displaying tabs
|
|
//If we don't do this, dragged element won't be visible on the other tab not displayed at
|
|
//first (for reminder, GLPI tabs are displayed dynamically on-demand)
|
|
echo "<div id='redips_clone'></div>";
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>".__('Name')." :</td>";
|
|
echo "<td>";
|
|
Html::autocompletionTextField($this, 'name', ['size' => 40]);
|
|
echo "</td>";
|
|
|
|
echo "<td>".__('Comments')." :</td>";
|
|
echo "<td>";
|
|
echo "<textarea cols='40' rows='2' name='comment' >".$this->fields["comment"]."</textarea>";
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>".__('Enable deploy on demand for the following group', 'fusioninventory')." :</td>";
|
|
echo "<td>";
|
|
PluginFusioninventoryDeployGroup::dropdown(['value' => $this->fields["plugin_fusioninventory_deploygroups_id"]]);
|
|
echo "</td>";
|
|
|
|
echo "<td colspan='2'></td>";
|
|
echo "</tr>";
|
|
|
|
$this->showFormButtons($options);
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* Display order type form
|
|
*
|
|
* @global array $CFG_GLPI
|
|
*/
|
|
function displayOrderTypeForm() {
|
|
global $CFG_GLPI;
|
|
|
|
$subtypes = [
|
|
'check' => __("Audits", 'fusioninventory'),
|
|
'file' => __("Files", 'fusioninventory'),
|
|
'action' => __("Actions", 'fusioninventory'),
|
|
'userinteraction' => __("User interactions", 'fusioninventory')
|
|
];
|
|
$json_subtypes = [
|
|
'check' => 'checks',
|
|
'file' => 'associatedFiles',
|
|
'action' => 'actions',
|
|
'userinteraction' => 'userinteractions'
|
|
];
|
|
|
|
$rand = mt_rand();
|
|
$datas = json_decode($this->fields['json'], true);
|
|
|
|
echo "<table class='tab_cadre_fixe' id='package_order_".$this->getID()."'>";
|
|
|
|
// Display an error if the package modification is not possible
|
|
$canedit = $this->canUpdateContent();
|
|
$error_msg = $this->getEditErrorMessage();
|
|
if (!empty($error_msg)) {
|
|
echo "<tr><td>$error_msg</td></tr>";
|
|
}
|
|
|
|
// Display the lists of each subtypes of a package
|
|
foreach ($subtypes as $subtype => $label) {
|
|
echo "<tr>";
|
|
echo "<th id='th_title_{$subtype}_$rand'>";
|
|
echo "<img src='".Plugin::getWebDir('fusioninventory')."/pics/$subtype.png' />";
|
|
echo " ".__($label, 'fusioninventory');
|
|
if ($canedit) {
|
|
$this->plusButtonSubtype($this->getID(), $subtype, $rand);
|
|
}
|
|
echo "</th>";
|
|
echo "</tr>";
|
|
|
|
/**
|
|
* File's form must be encoded as multipart/form-data
|
|
**/
|
|
$multipart = "";
|
|
if ($subtype == "file") {
|
|
$multipart = "enctype='multipart/form-data'";
|
|
}
|
|
echo "<tr>";
|
|
echo "<td style='vertical-align:top'>";
|
|
|
|
/**
|
|
* Display subtype form
|
|
**/
|
|
echo "<form name='addition$subtype' method='post' ".$multipart.
|
|
" action='deploypackage.form.php'>";
|
|
echo "<input type='hidden' name='id' value='".$this->getID()."' />";
|
|
echo "<input type='hidden' name='itemtype' value='PluginFusioninventoryDeploy".
|
|
ucfirst($subtype)."' />";
|
|
|
|
$classname = "PluginFusioninventoryDeploy".ucfirst($subtype);
|
|
$class = new $classname();
|
|
$class->displayForm($this, $datas, $rand, "init");
|
|
Html::closeForm();
|
|
|
|
$json_subtype = $json_subtypes[$subtype];
|
|
/**
|
|
* Display stored actions datas
|
|
**/
|
|
if (isset($datas['jobs'][$json_subtype])
|
|
&& !empty($datas['jobs'][$json_subtype])) {
|
|
echo "<div id='drag_deploypackage_". $subtype . "s'>";
|
|
echo "<form name='remove" . $subtype. "s' ".
|
|
"method='post' action='deploypackage.form.php' ".
|
|
"id='" . $subtype . "sList" . $rand . "'>";
|
|
echo Html::hidden('remove_item');
|
|
echo Html::hidden('itemtype', ['value' => $classname]);
|
|
echo Html::hidden('packages_id', ['value' => $this->getID()]);
|
|
$class->displayList($this, $datas, $rand);
|
|
Html::closeForm();
|
|
echo "</div>";
|
|
}
|
|
|
|
/**
|
|
* Initialize drag and drop on subtype lists
|
|
**/
|
|
echo "<script type='text/javascript'>";
|
|
echo "redipsInit('deploypackage', '$subtype', '".$this->getID()."');";
|
|
echo "</script>";
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
}
|
|
|
|
echo "</table>";
|
|
}
|
|
|
|
|
|
/**
|
|
* 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 "<img id='plus_{$subtype}s_block{$rand}'";
|
|
echo " onclick=\"new_subtype('{$subtype}', {$id}, {$rand})\" ";
|
|
echo " title='".__('Add')."' alt='".__('Add')."' ";
|
|
echo " class='pointer' src='".
|
|
$CFG_GLPI["root_doc"].
|
|
"/pics/add_dropdown.png' /> ";
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 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 "<img id='plus_$dom_id' ";
|
|
if ($clone !== false) {
|
|
echo " onClick=\"plusbutton('$dom_id', '$clone')\" ";
|
|
} else {
|
|
echo " onClick=\"plusbutton('$dom_id')\" ";
|
|
}
|
|
echo " title='".__('Add')."' alt='".__('Add')."' ";
|
|
echo " class='pointer' src='".$CFG_GLPI["root_doc"].
|
|
"/pics/add_dropdown.png'> ";
|
|
}
|
|
|
|
|
|
/**
|
|
* When user is in DEBUG mode, we display the json
|
|
*
|
|
* @global array $CFG_GLPI
|
|
*/
|
|
function showDebug() {
|
|
global $CFG_GLPI;
|
|
|
|
echo "<table class='tab_cadre_fixe'>";
|
|
echo "<tr><th>".__('JSON package representation', 'fusioninventory')."</th></tr>";
|
|
echo "<tr><td>";
|
|
echo "<textarea cols='132' rows='50' style='border:1' name='json'>";
|
|
echo PluginFusioninventoryToolbox::formatJson($this->fields['json']);
|
|
echo "</textarea></td></tr>";
|
|
echo "</table>";
|
|
}
|
|
|
|
|
|
/**
|
|
* Update the json structure
|
|
*
|
|
* @param string $action_type type of action
|
|
* @param array $params data used to update the json
|
|
*/
|
|
static function alterJSON($action_type, $params) {
|
|
//route to sub class
|
|
$item_type = $params['itemtype'];
|
|
|
|
if (in_array($item_type, [
|
|
'PluginFusioninventoryDeployCheck',
|
|
'PluginFusioninventoryDeployFile',
|
|
'PluginFusioninventoryDeployAction',
|
|
'PluginFusioninventoryDeployUserinteraction'
|
|
])) {
|
|
$class = new $item_type();
|
|
switch ($action_type) {
|
|
|
|
case "add_item" :
|
|
return $class->add_item($params);
|
|
break;
|
|
|
|
case "save_item" :
|
|
return $class->save_item($params);
|
|
break;
|
|
|
|
case "remove_item" :
|
|
return $class->remove_item($params);
|
|
break;
|
|
|
|
case "move_item" :
|
|
return $class->move_item($params);
|
|
break;
|
|
|
|
}
|
|
} else {
|
|
Toolbox::logDebug("package subtype not found : " . $params['itemtype']);
|
|
Html::displayErrorAndDie ("package subtype not found");
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Export the package (information, actions, files...)
|
|
*
|
|
* @param integer $packages_id id of the package to export
|
|
*/
|
|
function exportPackage($packages_id) {
|
|
$this->getFromDB($packages_id);
|
|
if (empty($this->fields['uuid'])) {
|
|
$input = [
|
|
'id' => $this->fields['id'],
|
|
'uuid' => Rule::getUuid()
|
|
];
|
|
$this->update($input);
|
|
}
|
|
|
|
$pfDeployFile = new PluginFusioninventoryDeployFile();
|
|
|
|
// Generate JSON
|
|
$input = $this->fields;
|
|
unset($input['id']);
|
|
$a_xml = [
|
|
'package' => $input,
|
|
'files' => [],
|
|
'manifests' => [],
|
|
'repository' => [],
|
|
'orders' => [['json' => $this->fields['json']]],
|
|
];
|
|
$json = json_decode($this->fields['json'], true);
|
|
$a_files = $json['associatedFiles'];
|
|
|
|
// Add files
|
|
foreach ($a_files as $files_id=>$data) {
|
|
$a_pkgfiles = current($pfDeployFile->find(['sha512' => $files_id], [], 1));
|
|
if (count($a_pkgfiles) > 0) {
|
|
unset($a_pkgfiles['id']);
|
|
$a_xml['files'][] = $a_pkgfiles;
|
|
}
|
|
}
|
|
|
|
// Create zip with JSON and files
|
|
$name = preg_replace("/[^a-zA-Z0-9]/", '', $this->fields['name']);
|
|
$filename = GLPI_PLUGIN_DOC_DIR."/fusioninventory/files/export/".$this->fields['uuid'].".".$name.".zip";
|
|
if (file_exists($filename)) {
|
|
unlink($filename);
|
|
}
|
|
|
|
$zip = new ZipArchive();
|
|
if ($zip->open($filename) == true) {
|
|
if ($zip->open($filename, ZipArchive::CREATE) == true) {
|
|
$zip->addEmptyDir('files');
|
|
$zip->addEmptyDir('files/manifests');
|
|
$zip->addEmptyDir('files/repository');
|
|
$pfDeployFile = new PluginFusioninventoryDeployFile();
|
|
foreach ($a_files as $hash=>$data) {
|
|
$sha512 = trim(file_get_contents(PLUGIN_FUSIONINVENTORY_MANIFESTS_DIR.$hash));
|
|
$zip->addFile(PLUGIN_FUSIONINVENTORY_MANIFESTS_DIR.$hash, "files/manifests/".$hash);
|
|
$a_xml['manifests'][] = $hash;
|
|
$file = $pfDeployFile->getDirBySha512($sha512).
|
|
"/".$sha512;
|
|
$zip->addFile(GLPI_PLUGIN_DOC_DIR."/fusioninventory/files/repository/".$file, "files/repository/".$file);
|
|
$a_xml['repository'][] = $file;
|
|
}
|
|
$json_string = json_encode($a_xml);
|
|
$zip->addFromString('information.json', $json_string);
|
|
}
|
|
$zip->close();
|
|
Session::addMessageAfterRedirect(__("Package exported in", "fusioninventory")." ".GLPI_PLUGIN_DOC_DIR."/fusioninventory/files/export/".$this->fields['uuid'].".".$name.".zip");
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Import the package
|
|
*
|
|
* @param string $zipfile the zip file with all data inside
|
|
*/
|
|
function importPackage($zipfile) {
|
|
|
|
$zip = new ZipArchive();
|
|
$pfDeployFile = new PluginFusioninventoryDeployFile();
|
|
|
|
$filename = GLPI_PLUGIN_DOC_DIR."/fusioninventory/files/import/".$zipfile;
|
|
|
|
$extract_folder = GLPI_PLUGIN_DOC_DIR."/fusioninventory/files/import/".$zipfile.".extract";
|
|
|
|
if ($zip->open($filename, ZipArchive::CREATE) == true) {
|
|
$zip->extractTo($extract_folder);
|
|
$zip->close();
|
|
}
|
|
$json_string = file_get_contents($extract_folder."/information.json");
|
|
|
|
$a_info = json_decode($json_string, true);
|
|
|
|
// Find package with this uuid
|
|
$a_packages = $this->find(['uuid' => $a_info['package']['uuid']]);
|
|
if (count($a_packages) == 0) {
|
|
// Create it
|
|
$_SESSION['tmp_clone_package'] = true;
|
|
$this->add($a_info['package']);
|
|
foreach ($a_info['files'] as $input) {
|
|
$pfDeployFile->add($input);
|
|
}
|
|
}
|
|
// Copy files
|
|
foreach ($a_info['manifests'] as $manifest) {
|
|
rename($extract_folder."/files/manifests/".$manifest, PLUGIN_FUSIONINVENTORY_MANIFESTS_DIR.$manifest);
|
|
}
|
|
foreach ($a_info['repository'] as $repository) {
|
|
$split = explode('/', $repository);
|
|
array_pop($split);
|
|
$folder = '';
|
|
foreach ($split as $dir) {
|
|
$folder .= '/'.$dir;
|
|
if (!file_exists(GLPI_PLUGIN_DOC_DIR."/fusioninventory/files/repository".$folder)) {
|
|
mkdir(GLPI_PLUGIN_DOC_DIR."/fusioninventory/files/repository".$folder);
|
|
}
|
|
}
|
|
rename($extract_folder."/files/repository/".$repository, GLPI_PLUGIN_DOC_DIR."/fusioninventory/files/repository/".$repository);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Display list of packages to import
|
|
*/
|
|
function listPackagesToImport() {
|
|
|
|
$rand = mt_rand();
|
|
|
|
echo "<div class='spaced'>";
|
|
Html::openMassiveActionsForm('mass'.__CLASS__.$rand);
|
|
|
|
$massiveactionparams = ['container' => 'mass'.__CLASS__.$rand];
|
|
Html::showMassiveActions($massiveactionparams);
|
|
echo "<table class='tab_cadre_fixe'>";
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<th colspan='5'>";
|
|
echo __('Packages to import', 'fusioninventory');
|
|
echo "</th>";
|
|
echo "</tr>";
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<th width='10'>".Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand)."</th>";
|
|
echo "<th>";
|
|
echo __('Name');
|
|
echo "</th>";
|
|
echo "<th>";
|
|
echo __('uuid');
|
|
echo "</th>";
|
|
echo "<th>";
|
|
echo __('Package to update');
|
|
echo "</th>";
|
|
echo "</tr>";
|
|
|
|
foreach (glob(GLPI_PLUGIN_DOC_DIR."/fusioninventory/files/import/*.zip") as $file) {
|
|
echo "<tr class='tab_bg_1'>";
|
|
$file = str_replace(GLPI_PLUGIN_DOC_DIR."/fusioninventory/files/import/", "", $file);
|
|
$split = explode('.', $file);
|
|
echo "<td>";
|
|
Html::showMassiveActionCheckBox(__CLASS__, $file);
|
|
echo "</td>";
|
|
echo "<td>";
|
|
echo $split[2];
|
|
echo "</td>";
|
|
echo "<td>";
|
|
echo $split[0].".".$split[1];
|
|
echo "</td>";
|
|
echo "<td>";
|
|
$a_packages = current($this->find(['uuid' => $split[0].".".$split[1]], [], 1));
|
|
if (count($a_packages) > 1) {
|
|
$this->getFromDB($a_packages['id']);
|
|
echo $this->getLink();
|
|
}
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
}
|
|
echo "</table>";
|
|
$massiveactionparams['ontop'] =false;
|
|
Html::showMassiveActions($massiveactionparams);
|
|
echo "</div>";
|
|
}
|
|
|
|
|
|
/**
|
|
* Get a sub element at index
|
|
*
|
|
* @param string $subtype
|
|
* @param integer $index
|
|
* @return string
|
|
*/
|
|
function getSubElement($subtype, $index) {
|
|
$data_o = json_decode($this->fields['json'], true);
|
|
return $data_o['jobs'][$subtype][$index];
|
|
}
|
|
|
|
|
|
/**
|
|
* Get Order's associated file by hash
|
|
*
|
|
* @param string $hash
|
|
* @return null|string
|
|
*/
|
|
function getAssociatedFile($hash) {
|
|
$data_o = json_decode($this->fields['json'], true);
|
|
|
|
if (array_key_exists( $hash, $data_o['associatedFiles'])) {
|
|
return $data_o['associatedFiles'][$hash];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the json
|
|
*
|
|
* @param integer $packages_id id of the order
|
|
* @return boolean|string the string is in json format
|
|
*/
|
|
static function getJson($packages_id) {
|
|
$pfDeployPackage = new self;
|
|
$pfDeployPackage->getFromDB($packages_id);
|
|
if (!empty($pfDeployPackage->fields['json'])) {
|
|
return $pfDeployPackage->fields['json'];
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Update the order json
|
|
*
|
|
* @param integer $packages_id
|
|
* @param array $datas
|
|
* @return integer error number
|
|
*/
|
|
static function updateOrderJson($packages_id, $datas) {
|
|
$pfDeployPackage = new self;
|
|
$options = JSON_UNESCAPED_SLASHES;
|
|
|
|
$json = json_encode($datas, $options);
|
|
|
|
$json_error_consts = [
|
|
JSON_ERROR_NONE => "JSON_ERROR_NONE",
|
|
JSON_ERROR_DEPTH => "JSON_ERROR_DEPTH",
|
|
JSON_ERROR_STATE_MISMATCH => "JSON_ERROR_STATE_MISMATCH",
|
|
JSON_ERROR_CTRL_CHAR => "JSON_ERROR_CTRL_CHAR",
|
|
JSON_ERROR_SYNTAX => "JSON_ERROR_SYNTAX",
|
|
JSON_ERROR_UTF8 => "JSON_ERROR_UTF8"
|
|
];
|
|
|
|
$error_json = json_last_error();
|
|
|
|
if (version_compare(PHP_VERSION, '5.5.0', "ge")) {
|
|
$error_json_message = json_last_error_msg();
|
|
} else {
|
|
$error_json_message = "";
|
|
}
|
|
$error = 0;
|
|
if ($error_json != JSON_ERROR_NONE) {
|
|
$error_msg = $json_error_consts[$error_json];
|
|
Session::addMessageAfterRedirect(
|
|
__("The modified JSON contained a syntax error :", "fusioninventory") . "<br/>" .
|
|
$error_msg . "<br/>". $error_json_message, false, ERROR, false
|
|
);
|
|
$error = 1;
|
|
} else {
|
|
$error = $pfDeployPackage->update(
|
|
[
|
|
'id' => $packages_id,
|
|
'json' => Toolbox::addslashes_deep($json)
|
|
]
|
|
);
|
|
}
|
|
return $error;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the tab name used for item
|
|
*
|
|
* @param object $item the item object
|
|
* @param integer $withtemplate 1 if is a template form
|
|
* @return string name of the tab
|
|
*/
|
|
function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) {
|
|
|
|
if (!$withtemplate) {
|
|
switch ($item->getType()) {
|
|
|
|
case __CLASS__ :
|
|
if ($item->canUpdateItem()) {
|
|
$tabs = [];
|
|
if ($item->fields['id'] > 0) {
|
|
$tabs[1] = __('Package actions', 'fusioninventory');
|
|
}
|
|
if ($item->fields['plugin_fusioninventory_deploygroups_id'] > 0) {
|
|
if ($_SESSION['glpishow_count_on_tabs']) {
|
|
$nb = $item->countVisibilities();
|
|
$tabs[2] = self::createTabEntry(_n('Target for deploy on demand',
|
|
'Targets for deploy on demand',
|
|
$nb, 'fusioninventory'),
|
|
$nb);
|
|
} else {
|
|
$tabs[2] = _n('Target for deploy on demand',
|
|
'Targets for deploy on demand', 2,
|
|
'fusioninventory');
|
|
}
|
|
}
|
|
return $tabs;
|
|
}
|
|
|
|
case 'Computer':
|
|
if (Session::haveRight("plugin_fusioninventory_selfpackage", READ)
|
|
&& PluginFusioninventoryToolbox::isAFusionInventoryDevice($item)
|
|
&& self::isDeployEnabled($item->fields['id'])) {
|
|
return __('Package deploy', 'fusioninventory');
|
|
}
|
|
}
|
|
}
|
|
return '';
|
|
}
|
|
|
|
|
|
/**
|
|
* Display the content of the tab
|
|
*
|
|
* @param object $item
|
|
* @param integer $tabnum number of the tab to display
|
|
* @param integer $withtemplate 1 if is a template form
|
|
* @return boolean
|
|
*/
|
|
static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) {
|
|
|
|
if ($item->getType() == __CLASS__) {
|
|
if ($tabnum == 2) {
|
|
$item->showVisibility();
|
|
return true;
|
|
} else if ($tabnum == 1) {
|
|
$item->displayOrderTypeForm();
|
|
return true;
|
|
}
|
|
} else if ($item->getType() == 'Computer') {
|
|
$package = new self();
|
|
$package->showPackageForMe($_SESSION['glpiID'], $item);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Count number elements for the visibility
|
|
*
|
|
* @return integer
|
|
*/
|
|
function countVisibilities() {
|
|
return (count($this->entities)
|
|
+ count($this->users)
|
|
+ count($this->groups)
|
|
+ count($this->profiles));
|
|
}
|
|
|
|
|
|
/**
|
|
* Display the visibility, so who can read. write...
|
|
*
|
|
* @global array $CFG_GLPI
|
|
* @return true
|
|
*/
|
|
function showVisibility() {
|
|
global $CFG_GLPI;
|
|
|
|
$ID = $this->fields['id'];
|
|
$canedit = $this->can($ID, UPDATE);
|
|
|
|
echo "<div class='center'>";
|
|
|
|
$rand = mt_rand();
|
|
$nb = count($this->users) + count($this->groups) + count($this->profiles)
|
|
+ count($this->entities);
|
|
|
|
if ($canedit) {
|
|
echo "<div class='firstbloc'>";
|
|
echo "<form name='deploypackagevisibility_form$rand' id='deploypackagevisibility_form$rand' ";
|
|
echo " method='post' action='".Toolbox::getItemTypeFormURL('PluginFusioninventoryDeployPackage')."'>";
|
|
echo "<input type='hidden' name='plugin_fusioninventory_deploypackages_id' value='$ID'>";
|
|
echo "<table class='tab_cadre_fixe'>";
|
|
echo "<tr class='tab_bg_1'><th colspan='4'>".__('Add a target for self-service', 'fusioninventory')."</th></tr>";
|
|
echo "<tr class='tab_bg_2'><td width='100px'>";
|
|
|
|
$types = ['Entity', 'Group', 'Profile', 'User'];
|
|
|
|
$addrand = Dropdown::showItemTypes('_type', $types);
|
|
$params = ['type' => '__VALUE__',
|
|
'right' => 'plugin_fusioninventory_selfpackage'];
|
|
|
|
Ajax::updateItemOnSelectEvent("dropdown__type".$addrand, "visibility$rand",
|
|
$CFG_GLPI["root_doc"]."/ajax/visibility.php",
|
|
$params);
|
|
|
|
echo "</td>";
|
|
echo "<td><span id='visibility$rand'></span>";
|
|
echo "</td></tr>";
|
|
echo "</table>";
|
|
Html::closeForm();
|
|
echo "</div>";
|
|
}
|
|
|
|
echo "<div class='spaced'>";
|
|
if ($canedit && $nb) {
|
|
Html::openMassiveActionsForm('mass'.__CLASS__.$rand);
|
|
$massiveactionparams
|
|
= ['num_displayed'
|
|
=> $nb,
|
|
'container'
|
|
=> 'mass'.__CLASS__.$rand,
|
|
'specific_actions'
|
|
=> ['delete' => _x('button', 'Delete permanently')] ];
|
|
Html::showMassiveActions($massiveactionparams);
|
|
}
|
|
echo "<table class='tab_cadre_fixehov'>";
|
|
$header_begin = "<tr>";
|
|
$header_top = '';
|
|
$header_bottom = '';
|
|
$header_end = '';
|
|
if ($canedit && $nb) {
|
|
$header_begin .= "<th width='10'>";
|
|
$header_top .= Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand);
|
|
$header_bottom .= Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand);
|
|
$header_end .= "</th>";
|
|
}
|
|
$header_end .= "<th>".__('Type')."</th>";
|
|
$header_end .= "<th>"._n('Recipient', 'Recipients', Session::getPluralNumber())."</th>";
|
|
$header_end .= "</tr>";
|
|
echo $header_begin.$header_top.$header_end;
|
|
|
|
// Users
|
|
if (count($this->users)) {
|
|
foreach ($this->users as $key => $val) {
|
|
foreach ($val as $data) {
|
|
echo "<tr class='tab_bg_1'>";
|
|
if ($canedit) {
|
|
echo "<td>";
|
|
Html::showMassiveActionCheckBox('PluginFusioninventoryDeployPackage_User', $data["id"]);
|
|
echo "</td>";
|
|
}
|
|
echo "<td>".__('User')."</td>";
|
|
echo "<td>".getUserName($data['users_id'])."</td>";
|
|
echo "</tr>";
|
|
}
|
|
}
|
|
}
|
|
|
|
// Groups
|
|
if (count($this->groups)) {
|
|
foreach ($this->groups as $key => $val) {
|
|
foreach ($val as $data) {
|
|
echo "<tr class='tab_bg_1'>";
|
|
if ($canedit) {
|
|
echo "<td>";
|
|
Html::showMassiveActionCheckBox('PluginFusioninventoryDeployPackage_Group', $data["id"]);
|
|
echo "</td>";
|
|
}
|
|
echo "<td>".__('Group')."</td>";
|
|
echo "<td>";
|
|
$names = Dropdown::getDropdownName('glpi_groups', $data['groups_id'], 1);
|
|
$groupname = sprintf(__('%1$s %2$s'), $names["name"],
|
|
Html::showToolTip($names["comment"], ['display' => false]));
|
|
if ($data['entities_id'] >= 0) {
|
|
$groupname = sprintf(__('%1$s / %2$s'), $groupname,
|
|
Dropdown::getDropdownName('glpi_entities',
|
|
$data['entities_id']));
|
|
if ($data['is_recursive']) {
|
|
$groupname = sprintf(__('%1$s %2$s'), $groupname,
|
|
"<span class='b'>(".__('R').")</span>");
|
|
}
|
|
}
|
|
echo $groupname;
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
}
|
|
}
|
|
}
|
|
|
|
// Entity
|
|
if (count($this->entities)) {
|
|
foreach ($this->entities as $key => $val) {
|
|
foreach ($val as $data) {
|
|
echo "<tr class='tab_bg_1'>";
|
|
if ($canedit) {
|
|
echo "<td>";
|
|
Html::showMassiveActionCheckBox('PluginFusioninventoryDeployPackage_Entity', $data["id"]);
|
|
echo "</td>";
|
|
}
|
|
echo "<td>".Entity::getTypeName(1)."</td>";
|
|
echo "<td>";
|
|
$names = Dropdown::getDropdownName('glpi_entities', $data['entities_id'], 1);
|
|
$entityname = sprintf(__('%1$s %2$s'), $names["name"],
|
|
Html::showToolTip($names["comment"], ['display' => false]));
|
|
if ($data['is_recursive']) {
|
|
$entityname = sprintf(__('%1$s %2$s'), $entityname,
|
|
"<span class='b'>(".__('R').")</span>");
|
|
}
|
|
echo $entityname;
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
}
|
|
}
|
|
}
|
|
|
|
// Profiles
|
|
if (count($this->profiles)) {
|
|
foreach ($this->profiles as $key => $val) {
|
|
foreach ($val as $data) {
|
|
echo "<tr class='tab_bg_1'>";
|
|
if ($canedit) {
|
|
echo "<td>";
|
|
Html::showMassiveActionCheckBox('PluginFusioninventoryDeployPackage_Profile', $data["id"]);
|
|
echo "</td>";
|
|
}
|
|
echo "<td>"._n('Profile', 'Profiles', 1)."</td>";
|
|
echo "<td>";
|
|
$names = Dropdown::getDropdownName('glpi_profiles', $data['profiles_id'], 1);
|
|
$profilename = sprintf(__('%1$s %2$s'), $names["name"],
|
|
Html::showToolTip($names["comment"], ['display' => false]));
|
|
if ($data['entities_id'] >= 0) {
|
|
$profilename = sprintf(__('%1$s / %2$s'), $profilename,
|
|
Dropdown::getDropdownName('glpi_entities',
|
|
$data['entities_id']));
|
|
if ($data['is_recursive']) {
|
|
$profilename = sprintf(__('%1$s %2$s'), $profilename,
|
|
"<span class='b'>(".__('R').")</span>");
|
|
}
|
|
}
|
|
echo $profilename;
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
}
|
|
}
|
|
}
|
|
if ($nb) {
|
|
echo $header_begin.$header_bottom.$header_end;
|
|
}
|
|
|
|
echo "</table>";
|
|
if ($canedit && $nb) {
|
|
$massiveactionparams['ontop'] =false;
|
|
Html::showMassiveActions($massiveactionparams);
|
|
Html::closeForm();
|
|
}
|
|
|
|
echo "</div>";
|
|
|
|
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 "<form name='onetimedeploy_form' id='onetimedeploy_form'
|
|
method='POST'
|
|
action='$url/front/deploypackage.public.php'
|
|
enctype=\"multipart/form-data\">";
|
|
|
|
echo "<table class='tab_cadre_fixe'>";
|
|
foreach ($my_packages as $computers_id => $data) {
|
|
|
|
$package_to_install = [];
|
|
$computer->getFromDB($computers_id);
|
|
echo "<tr>";
|
|
echo "<th><img src='$url/pics/computer_icon.png'/> "
|
|
.__('Computer', 'Computers', 1)." <i>"
|
|
.$computer->fields['name']."</i></th>";
|
|
echo "</tr>";
|
|
|
|
if (count($data)) {
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>";
|
|
echo '<div class="target_block">';
|
|
echo '<div class="target_details">';
|
|
echo '<div class="target_stats">';
|
|
foreach ($data as $packages_id => $package_info) {
|
|
if (isset($package_info['taskjobs_id'])) {
|
|
$taskjob_id = $package_info['taskjobs_id'];
|
|
echo "<div class='counter_block ".$package_info['last_taskjobstate']['state']."'
|
|
id='block_$taskjob_id'>";
|
|
// display deploy informations
|
|
echo "<table>";
|
|
echo "<tr>";
|
|
echo "<td style='min-width: 600px'>";
|
|
|
|
// add a toggle control
|
|
if ($is_tech) {
|
|
echo "<a class='toggle_run'
|
|
href='#'
|
|
id='toggle_run_$taskjob_id'>";
|
|
echo $package_info['name'];
|
|
echo "</a>";
|
|
} else {
|
|
echo $package_info['name'];
|
|
}
|
|
echo "</td>";
|
|
echo "<td style='width: 200px'>";
|
|
echo Html::convDateTime($package_info['last_taskjobstate']['date']);
|
|
echo "</td>";
|
|
echo "<td style='width: 200px'>";
|
|
echo self::getDeploymentLabelForAState($package_info['last_taskjobstate']['state']);
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
echo "</table>";
|
|
|
|
if ($is_tech) {
|
|
// display also last log (folded)
|
|
echo "<div class='agent_block'
|
|
id='run_$taskjob_id'
|
|
style='display:none;'>";
|
|
|
|
echo "<div class='buttons'>";
|
|
|
|
// if job is in error, suggest restart
|
|
if (in_array($package_info['last_taskjobstate']['state'],
|
|
["agents_error", "agents_success"])) {
|
|
echo "<a class='restart btn'
|
|
href='#'
|
|
title='".__("Restart job", 'fusioninventory')."'
|
|
id='restart_run_$taskjob_id'>
|
|
<i class='fa fa-bolt'></i></a>";
|
|
}
|
|
|
|
// if job has not started, user can cancel it
|
|
if ($package_info['last_taskjobstate']['state'] == "agents_prepared") {
|
|
echo "<a class='cancel btn'
|
|
href='#'
|
|
title='".__("Cancel job", 'fusioninventory')."'
|
|
id='cancel_run_$taskjob_id'>
|
|
<i class='fa fa-stop'></i></a>";
|
|
}
|
|
|
|
// permits to "soft" refresh
|
|
echo "<a href='#'
|
|
title='".__("refresh job", 'fusioninventory')."'
|
|
class='btn'
|
|
id='refresh_run_$taskjob_id'>
|
|
<i class='fa fa-refresh fa-fx'></i></a>";
|
|
|
|
echo "</div>"; // .buttons
|
|
|
|
// log list
|
|
echo "<table class='runs' id='runs_$taskjob_id'>";
|
|
foreach ($package_info['last_taskjobstate']['logs'] as $log) {
|
|
echo "<tr class='run log'>";
|
|
echo "<td>".$log['log.f_date']."</td>";
|
|
echo "<td>".$joblogs_labels[$log['log.state']]."</td>";
|
|
echo "<td>".$log['log.comment']."</td>";
|
|
echo "</tr>";
|
|
}
|
|
echo "</table>"; // .runs
|
|
echo '</div>'; // .agent_block
|
|
}
|
|
|
|
echo '</div>'; // .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(
|
|
'<tr>'+
|
|
'<td>'+log['log.f_date']+'</td>'+
|
|
'<td>'+logstatuses_names[log['log.state']]+'</td>'+
|
|
'<td>'+log['log.comment']+'</td>'+
|
|
'<tr>'
|
|
)
|
|
});
|
|
|
|
var class_to_apply = '';
|
|
switch (data.logs[0]['log.state']) {
|
|
case '".PluginFusioninventoryTaskjoblog::TASK_RUNNING."':
|
|
class_to_apply = 'agents_running';
|
|
break;
|
|
case '".PluginFusioninventoryTaskjoblog::TASK_ERROR."':
|
|
class_to_apply = 'agents_error';
|
|
break;
|
|
case '".PluginFusioninventoryTaskjoblog::TASK_OK."':
|
|
class_to_apply = 'agents_success';
|
|
break;
|
|
}
|
|
if (class_to_apply.length) {
|
|
$('#block_$taskjob_id')
|
|
.attr('class', 'counter_block '+class_to_apply);
|
|
}
|
|
}
|
|
},
|
|
complete: function() {
|
|
setTimeout(function() {
|
|
fa.removeClass('fa-spin fa-spinner')
|
|
.addClass('fa-refresh');
|
|
}, 300);
|
|
}
|
|
});
|
|
})
|
|
});");
|
|
} else {
|
|
$package_to_install[$packages_id] = $package_info['name'];
|
|
}
|
|
}
|
|
echo '</div>'; // .target_stats
|
|
echo '</div>'; // .target_details
|
|
echo '</div>'; // .target_block
|
|
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
}
|
|
|
|
if (count($package_to_install)) {
|
|
|
|
$p['name'] = 'deploypackages_'.$computers_id;
|
|
$p['display'] = true;
|
|
$p['multiple'] = true;
|
|
$p['size'] = 3;
|
|
$p['width'] = 950;
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>";
|
|
echo __('Select packages you want install', 'fusioninventory');
|
|
echo "<br/>";
|
|
Dropdown::showFromArray($p['name'], $package_to_install, $p);
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
|
|
echo "<tr>";
|
|
echo "<th colspan='2'>";
|
|
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 "</th>";
|
|
echo "</tr>";
|
|
} else {
|
|
echo "<tr>";
|
|
echo "<th colspan='2'>";
|
|
echo __('No packages available to install', 'fusioninventory');
|
|
echo "</th>";
|
|
echo "</tr>";
|
|
}
|
|
}
|
|
echo "</table>"; // .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;
|
|
}
|
|
}
|