2087 lines
67 KiB
PHP
2087 lines
67 KiB
PHP
<?php
|
|
/**
|
|
* ---------------------------------------------------------------------
|
|
* GLPI - Gestionnaire Libre de Parc Informatique
|
|
* Copyright (C) 2015-2020 Teclib' and contributors.
|
|
*
|
|
* http://glpi-project.org
|
|
*
|
|
* based on GLPI - Gestionnaire Libre de Parc Informatique
|
|
* Copyright (C) 2003-2014 by the INDEPNET Development Team.
|
|
*
|
|
* ---------------------------------------------------------------------
|
|
*
|
|
* LICENSE
|
|
*
|
|
* This file is part of GLPI.
|
|
*
|
|
* GLPI is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* GLPI 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with GLPI. If not, see <http://www.gnu.org/licenses/>.
|
|
* ---------------------------------------------------------------------
|
|
*/
|
|
|
|
use Glpi\Event;
|
|
|
|
if (!defined('GLPI_ROOT')) {
|
|
die("Sorry. You can't access this file directly");
|
|
}
|
|
|
|
class RuleCollection extends CommonDBTM {
|
|
/// Rule type
|
|
public $sub_type;
|
|
/// process collection stop on first matched rule
|
|
public $stop_on_first_match = false;
|
|
/// field used to order rules
|
|
public $orderby = "ranking";
|
|
/// Processing several rules : use result of the previous one to computer the current one
|
|
public $use_output_rule_process_as_next_input = false;
|
|
/// Rule collection can be replay (for dictionnary)
|
|
public $can_replay_rules = false;
|
|
/// List of rules of the rule collection
|
|
public $RuleList = null;
|
|
/// Menu type
|
|
public $menu_type = "rule";
|
|
/// Menu option
|
|
public $menu_option = "";
|
|
|
|
public $entity = 0;
|
|
|
|
static $rightname = 'config';
|
|
|
|
|
|
|
|
/// Tab orientation : horizontal or vertical
|
|
public $taborientation = 'horizontal';
|
|
|
|
static function getTable($classname = null) {
|
|
return parent::getTable('Rule');
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $entity (default 0)
|
|
**/
|
|
function setEntity($entity = 0) {
|
|
$this->entity = $entity;
|
|
}
|
|
|
|
|
|
function canList() {
|
|
return static::canView();
|
|
}
|
|
|
|
|
|
function isEntityAssign() {
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get Collection Size : retrieve the number of rules
|
|
*
|
|
* @param boolean $recursive (true by default)
|
|
* @param integer $condition (0 by default)
|
|
*
|
|
* @return : number of rules
|
|
**/
|
|
function getCollectionSize($recursive = true, $condition = 0) {
|
|
global $DB;
|
|
|
|
$restrict = $this->getRuleListCriteria([
|
|
'condition' => $condition,
|
|
'active' => false
|
|
]);
|
|
|
|
$iterator = $DB->request($restrict);
|
|
return count($iterator);
|
|
}
|
|
|
|
|
|
/**
|
|
* Get rules list criteria
|
|
*
|
|
* @param array $options Options
|
|
*
|
|
* @return array
|
|
**/
|
|
function getRuleListCriteria($options = []) {
|
|
|
|
$p['active'] = true;
|
|
$p['start'] = 0;
|
|
$p['limit'] = 0;
|
|
$p['inherited'] = 1;
|
|
$p['childrens'] = 0;
|
|
$p['condition'] = 0;
|
|
|
|
foreach ($options as $key => $value) {
|
|
$p[$key] = $value;
|
|
}
|
|
|
|
$criteria = [
|
|
'SELECT' => Rule::getTable() . '.*',
|
|
'FROM' => Rule::getTable(),
|
|
'ORDER' => [
|
|
$this->orderby . ' ASC'
|
|
]
|
|
];
|
|
|
|
$where = [];
|
|
if ($p['active']) {
|
|
$where['is_active'] = 1;
|
|
}
|
|
|
|
if ($p['condition'] > 0) {
|
|
$where['condition'] = ['&', (int)$p['condition']];
|
|
}
|
|
|
|
//Select all the rules of a different type
|
|
$where['sub_type'] = $this->getRuleClassName();
|
|
if ($this->isRuleRecursive()) {
|
|
$criteria['LEFT JOIN'] = [
|
|
Entity::getTable() => [
|
|
'ON' => [
|
|
Entity::getTable() => 'id',
|
|
Rule::getTable() => 'entities_id'
|
|
]
|
|
]
|
|
];
|
|
|
|
if (!$p['childrens']) {
|
|
$where += getEntitiesRestrictCriteria(
|
|
Rule::getTable(),
|
|
'entities_id',
|
|
$this->entity,
|
|
$p['inherited']
|
|
);
|
|
} else {
|
|
$sons = getSonsOf('glpi_entities', $this->entity);
|
|
$where[Rule::getTable() . '.entities_id'] = $sons;
|
|
}
|
|
|
|
$criteria['ORDER'] = [
|
|
Entity::getTable() . '.level ASC',
|
|
$this->orderby . ' ASC'
|
|
];
|
|
}
|
|
|
|
if ($p['limit']) {
|
|
$criteria['LIMIT'] = (int)$p['limit'];
|
|
$criteria['START'] = (int)$p['start'];
|
|
}
|
|
$criteria['WHERE'] = $where;
|
|
|
|
return $criteria;
|
|
}
|
|
|
|
/**
|
|
* Get Collection Part : retrieve descriptions of a range of rules
|
|
*
|
|
* @param $options array of options may be :
|
|
* - start : first rule (in the result set - default 0)
|
|
* - limit : max number of rules to retrieve (default 0)
|
|
* - recursive : boolean get recursive rules
|
|
* - childirens : boolean get childrens rules
|
|
**/
|
|
function getCollectionPart($options = []) {
|
|
global $DB;
|
|
|
|
$p['start'] = 0;
|
|
$p['limit'] = 0;
|
|
$p['recursive'] = true;
|
|
$p['childrens'] = 0;
|
|
$p['condition'] = 0;
|
|
|
|
foreach ($options as $key => $value) {
|
|
$p[$key] = $value;
|
|
}
|
|
|
|
// no need to use SingletonRuleList::getInstance because we read only 1 page
|
|
$this->RuleList = new SingletonRuleList();
|
|
$this->RuleList->list = [];
|
|
|
|
//Select all the rules of a different type
|
|
$criteria = $this->getRuleListCriteria($p);
|
|
$iterator = $DB->request($criteria);
|
|
|
|
while ($data = $iterator->next()) {
|
|
//For each rule, get a Rule object with all the criterias and actions
|
|
$tempRule = $this->getRuleClass();
|
|
$tempRule->fields = $data;
|
|
$this->RuleList->list[] = $tempRule;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Get Collection Datas : retrieve descriptions and rules
|
|
*
|
|
* @param $retrieve_criteria Retrieve the criterias of the rules ? (default 0)
|
|
* @param $retrieve_action Retrieve the action of the rules ? (default 0)
|
|
* @param $condition Retrieve with a specific condition
|
|
**/
|
|
function getCollectionDatas($retrieve_criteria = 0, $retrieve_action = 0, $condition = 0) {
|
|
global $DB;
|
|
|
|
if ($this->RuleList === null) {
|
|
$this->RuleList = SingletonRuleList::getInstance($this->getRuleClassName(),
|
|
$this->entity);
|
|
}
|
|
$need = 1+($retrieve_criteria?2:0)+($retrieve_action?4:0)+(8*$condition);
|
|
|
|
// check if load required
|
|
if (($need & $this->RuleList->load) != $need) {
|
|
//Select all the rules of a different type
|
|
$criteria = $this->getRuleListCriteria(['condition' => $condition]);
|
|
$iterator = $DB->request($criteria);
|
|
|
|
if (count($iterator)) {
|
|
$this->RuleList->list = [];
|
|
|
|
while ($rule = $iterator->next()) {
|
|
//For each rule, get a Rule object with all the criterias and actions
|
|
$tempRule = $this->getRuleClass();
|
|
|
|
if ($tempRule->getRuleWithCriteriasAndActions($rule["id"], $retrieve_criteria,
|
|
$retrieve_action)) {
|
|
//Add the object to the list of rules
|
|
$this->RuleList->list[] = $tempRule;
|
|
}
|
|
}
|
|
|
|
$this->RuleList->load = $need;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
function getRuleClassName() {
|
|
|
|
if (preg_match('/(.*)Collection/', get_class($this), $rule_class)) {
|
|
return $rule_class[1];
|
|
}
|
|
return "";
|
|
}
|
|
|
|
|
|
/**
|
|
* Get a instance of the class to manipulate rule of this collection
|
|
**/
|
|
function getRuleClass() {
|
|
|
|
$name = $this->getRuleClassName();
|
|
if ($name != '') {
|
|
return new $name();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
/**
|
|
* Is a confirmation needed before replay on DB ?
|
|
* If needed need to send 'replay_confirm' in POST
|
|
*
|
|
* @param $target filename : where to go when done
|
|
*
|
|
* @return true if confirmtion is needed, else false
|
|
**/
|
|
function warningBeforeReplayRulesOnExistingDB($target) {
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Replay Collection on DB
|
|
*
|
|
* @param $offset first row to work on (default 0)
|
|
* @param $maxtime float max system time to stop working (default 0)
|
|
* @param $items array containg items to replay. If empty -> all
|
|
* @param $params array additional parameters if needed
|
|
*
|
|
* @return -1 if all rows done, else offset for next run
|
|
**/
|
|
function replayRulesOnExistingDB($offset = 0, $maxtime = 0, $items = [], $params = []) {
|
|
}
|
|
|
|
|
|
/**
|
|
* Get title used in list of rules
|
|
*
|
|
* @return Title of the rule collection
|
|
**/
|
|
function getTitle() {
|
|
return __('Rules list');
|
|
}
|
|
|
|
|
|
/**
|
|
* Indicates if the rule can be affected to an entity or if it's global
|
|
**/
|
|
function isRuleEntityAssigned() {
|
|
|
|
$rule = $this->getRuleClass();
|
|
return $rule->isEntityAssign();
|
|
}
|
|
|
|
|
|
/**
|
|
* Indicates if the rule can be affected to an entity or if it's global
|
|
**/
|
|
function isRuleRecursive() {
|
|
|
|
$rule = $this->getRuleClass();
|
|
return $rule->maybeRecursive();
|
|
}
|
|
|
|
/**
|
|
* Indicates if the rule use conditions
|
|
**/
|
|
function isRuleUseConditions() {
|
|
|
|
$rule = $this->getRuleClass();
|
|
return $rule->useConditions();
|
|
}
|
|
|
|
/**
|
|
* Indicates if the rule use conditions
|
|
**/
|
|
function getDefaultRuleConditionForList() {
|
|
|
|
$rule = $this->getRuleClass();
|
|
$cond = $rule->getConditionsArray();
|
|
// Get max value
|
|
if (count($cond)) {
|
|
return max(array_keys($cond));
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
function showEngineSummary() {
|
|
|
|
echo "<table class='tab_cadre_fixe'><tr><th>";
|
|
|
|
//Display information about the how the rules engine process the rules
|
|
if ($this->stop_on_first_match) {
|
|
//The engine stop on the first matched rule
|
|
echo "<span class='center b'>".__('The engine stops on the first checked rule.').
|
|
"</span><br>";
|
|
|
|
} else {
|
|
//The engine process all the rules
|
|
echo "<span class='center b'>".__('The engine treats all the rules.')."</span><br>";
|
|
}
|
|
|
|
if ($this->use_output_rule_process_as_next_input) {
|
|
//The engine keep the result of a rule to be processed further
|
|
echo "<span class='center b'>".
|
|
__('The engine passes the result of a rule to the following one.')."</span><br>";
|
|
}
|
|
|
|
if ($this->isRuleUseConditions()) {
|
|
//The engine keep the result of a rule to be processed further
|
|
echo "<span class='center b'>".
|
|
__('Rules are conditionals. Each one can be used on multiple actions.');
|
|
echo "</span><br>";
|
|
}
|
|
|
|
echo "</th></tr>";
|
|
echo "</table>\n";
|
|
}
|
|
|
|
|
|
/**
|
|
* Show the list of rules
|
|
*
|
|
* @param $target
|
|
* @param $options array
|
|
*
|
|
* @return void
|
|
**/
|
|
function showListRules($target, $options = []) {
|
|
global $CFG_GLPI;
|
|
|
|
$p['inherited'] = 1;
|
|
$p['childrens'] = 0;
|
|
$p['active'] = false;
|
|
$p['condition'] = 0;
|
|
$rand = mt_rand();
|
|
|
|
foreach (['inherited','childrens', 'condition'] as $param) {
|
|
if (isset($options[$param])
|
|
&& $this->isRuleRecursive()) {
|
|
$p[$param] = $options[$param];
|
|
}
|
|
}
|
|
|
|
$rule = $this->getRuleClass();
|
|
$display_entities = ($this->isRuleRecursive()
|
|
&& ($p['inherited'] || $p['childrens']));
|
|
|
|
// Do not know what it is ?
|
|
$canedit = (self::canUpdate()
|
|
&& !$display_entities);
|
|
|
|
$use_conditions = false;
|
|
if ($rule->useConditions()) {
|
|
// First get saved option
|
|
$p['condition'] = Session::getSavedOption($this->getType(), 'condition', 0);
|
|
if ($p['condition'] == 0) {
|
|
$p['condition'] = $this->getDefaultRuleConditionForList();
|
|
}
|
|
$use_conditions = true;
|
|
// Mini Search engine
|
|
echo "<table class='tab_cadre_fixe'>";
|
|
echo "<tr class='tab_bg_1'><td class='center' width='50%'>";
|
|
echo __('Rules used for')."</td><td>";
|
|
$rule->dropdownConditions(['value' => $p['condition'],
|
|
'on_change' => 'reloadTab("start=0&inherited='.$p['inherited']
|
|
.'&childrens='.$p['childrens'].'&condition="+this.value)']);
|
|
echo "</td></tr></table>";
|
|
}
|
|
|
|
$nb = $this->getCollectionSize($p['inherited'], $p['condition']);
|
|
$p['start'] = (isset($options["start"]) ? $options["start"] : 0);
|
|
|
|
if ($p['start'] >= $nb) {
|
|
$p['start'] = 0;
|
|
}
|
|
|
|
$p['limit'] = $_SESSION['glpilist_limit'];
|
|
$this->getCollectionPart($p);
|
|
|
|
Html::printAjaxPager('', $p['start'], $nb);
|
|
|
|
Html::openMassiveActionsForm('mass'.__CLASS__.$rand);
|
|
echo "\n<div class='spaced'>";
|
|
|
|
if ($canedit && $nb) {
|
|
$massiveactionparams = ['num_displayed' => min($p['limit'], $nb),
|
|
'container' => 'mass'.__CLASS__.$rand,
|
|
'extraparams' => ['entity' => $this->entity,
|
|
'condition' => $p['condition'],
|
|
'rule_class_name'
|
|
=> $this->getRuleClassName()]];
|
|
Html::showMassiveActions($massiveactionparams);
|
|
}
|
|
|
|
echo "<table class='tab_cadre_fixehov'>";
|
|
$colspan = 6;
|
|
|
|
if ($display_entities) {
|
|
$colspan++;
|
|
}
|
|
if ($use_conditions) {
|
|
$colspan++;
|
|
}
|
|
echo "<tr><th colspan='$colspan'>" . $this->getTitle() ."</th></tr>\n";
|
|
|
|
echo "<tr>";
|
|
echo "<th>";
|
|
if ($canedit) {
|
|
echo Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand);
|
|
}
|
|
echo "</th>";
|
|
echo "<th>".__('Name')."</th>";
|
|
echo "<th>".__('Description')."</th>";
|
|
if ($use_conditions) {
|
|
echo "<th>".__('Use rule for')."</th>";
|
|
}
|
|
echo "<th>".__('Active')."</th>";
|
|
|
|
if ($display_entities) {
|
|
echo "<th>".Entity::getTypeName(1)."</th>\n";
|
|
}
|
|
if (!$display_entities) {
|
|
echo "<th colspan='2'> </th>";
|
|
}
|
|
echo "</tr>\n";
|
|
|
|
if (count($this->RuleList->list)) {
|
|
$ruletype = $this->RuleList->list[0]->getType();
|
|
Session::initNavigateListItems($ruletype);
|
|
}
|
|
|
|
for ($i=$p['start'],$j=0; isset($this->RuleList->list[$j]); $i++,$j++) {
|
|
$this->RuleList->list[$j]->showMinimalForm($target, $i==0, $i==$nb-1, $display_entities, $p['condition']);
|
|
Session::addToNavigateListItems($ruletype, $this->RuleList->list[$j]->fields['id']);
|
|
}
|
|
if ($nb) {
|
|
echo "<tr>";
|
|
echo "<th>";
|
|
if ($canedit) {
|
|
echo Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand);
|
|
}
|
|
echo "</th>";
|
|
echo "<th>".__('Name')."</th>";
|
|
echo "<th>".__('Description')."</th>";
|
|
if ($use_conditions) {
|
|
echo "<th>".__('Use rule for')."</th>";
|
|
}
|
|
echo "<th>".__('Active')."</th>";
|
|
|
|
if ($display_entities) {
|
|
echo "<th>".Entity::getTypeName(1)."</th>\n";
|
|
}
|
|
if (!$display_entities) {
|
|
echo "<th colspan='2'> </th>";
|
|
}
|
|
echo "</tr>\n";
|
|
}
|
|
echo "</table>\n";
|
|
|
|
if ($canedit && $nb) {
|
|
$massiveactionparams['ontop'] = false;
|
|
Html::showMassiveActions($massiveactionparams);
|
|
}
|
|
|
|
echo "</div>";
|
|
Html::closeForm();
|
|
|
|
Html::printAjaxPager('', $p['start'], $nb);
|
|
|
|
echo "<div class='spaced center'>";
|
|
|
|
if ($plugin = isPluginItemType($this->getType())) {
|
|
$url = $CFG_GLPI["root_doc"]."/plugins/".strtolower($plugin['plugin']);
|
|
} else {
|
|
$url = $CFG_GLPI["root_doc"];
|
|
}
|
|
|
|
echo "<a class='vsubmit' href='#' onClick=\"".
|
|
Html::jsGetElementbyID('allruletest'.$rand).".dialog('open'); return false;\">".
|
|
__('Test rules engine')."</a>";
|
|
Ajax::createIframeModalWindow('allruletest'.$rand,
|
|
$url."/front/rulesengine.test.php?".
|
|
"sub_type=".$this->getRuleClassName().
|
|
"&condition=".$p['condition'],
|
|
['title' => __('Test rules engine')]);
|
|
echo "</div>";
|
|
|
|
if ($this->can_replay_rules) {
|
|
echo "<div class='spaced center'>";
|
|
echo "<a class='vsubmit' href='".$rule->getSearchURL()."?replay_rule=replay_rule'>".
|
|
__s('Replay the dictionary rules')."</a>";
|
|
echo "</div>";
|
|
}
|
|
|
|
echo "<div class='spaced'>";
|
|
$this->showAdditionalInformationsInForm($target);
|
|
echo "</div>";
|
|
}
|
|
|
|
|
|
/**
|
|
* Show the list of rules
|
|
*
|
|
* @param $target
|
|
*
|
|
* @return void
|
|
**/
|
|
function showAdditionalInformationsInForm($target) {
|
|
}
|
|
|
|
|
|
/**
|
|
* Modify rule's ranking and automatically reorder all rules
|
|
*
|
|
* @param $ID the rule ID whose ranking must be modified
|
|
* @param $action up or down
|
|
* @param $condition action on a specific condition
|
|
**/
|
|
function changeRuleOrder($ID, $action, $condition = 0) {
|
|
global $DB;
|
|
|
|
$criteria = [
|
|
'SELECT' => 'ranking',
|
|
'FROM' => 'glpi_rules',
|
|
'WHERE' => ['id' => $ID]
|
|
];
|
|
|
|
$add_condition = [];
|
|
if ($condition > 0) {
|
|
$add_condition = ['condition' => ['&', (int)$condition]];
|
|
}
|
|
|
|
$iterator = $DB->request($criteria);
|
|
if (count($iterator) == 1) {
|
|
$result = $iterator->next();
|
|
$current_rank = $result['ranking'];
|
|
// Search rules to switch
|
|
$criteria = [
|
|
'SELECT' => ['id', 'ranking'],
|
|
'FROM' => 'glpi_rules',
|
|
'WHERE' => [
|
|
'sub_type' => $this->getRuleClassName()
|
|
] + $add_condition,
|
|
'LIMIT' => 1
|
|
];
|
|
|
|
switch ($action) {
|
|
case "up" :
|
|
$criteria['WHERE']['ranking'] = ['<', $current_rank];
|
|
$criteria['ORDERBY'] = 'ranking DESC';
|
|
break;
|
|
|
|
case "down" :
|
|
$criteria['WHERE']['ranking'] = ['>', $current_rank];
|
|
$criteria['ORDERBY'] = 'ranking ASC';
|
|
break;
|
|
|
|
default :
|
|
return false;
|
|
}
|
|
|
|
$iterator2 = $DB->request($criteria);
|
|
if (count($iterator2) == 1) {
|
|
$result2 = $iterator2->next();
|
|
$other_ID = $result2['id'];
|
|
$new_rank = $result2['ranking'];
|
|
echo $current_rank.' '.$ID.'<br>';
|
|
echo $new_rank.' '.$other_ID.'<br>';
|
|
|
|
$rule = $this->getRuleClass();
|
|
$result = false;
|
|
$criteria = [
|
|
'SELECT' => ['id', 'ranking'],
|
|
'FROM' => 'glpi_rules',
|
|
'WHERE' => ['sub_type' => $this->getRuleClassName()]
|
|
];
|
|
$diff = $new_rank - $current_rank;
|
|
switch ($action) {
|
|
case "up" :
|
|
$criteria['WHERE'] = array_merge(
|
|
$criteria['WHERE'], [
|
|
['ranking' => ['>', $new_rank]],
|
|
['ranking' => ['<=', $current_rank]]
|
|
]
|
|
);
|
|
$diff += 1;
|
|
break;
|
|
|
|
case "down" :
|
|
$criteria['WHERE'] = array_merge(
|
|
$criteria['WHERE'], [
|
|
['ranking' => ['>=', $current_rank]],
|
|
['ranking' => ['<', $new_rank]]
|
|
]
|
|
);
|
|
$diff -= 1;
|
|
break;
|
|
|
|
default :
|
|
return false;
|
|
}
|
|
|
|
if ($diff != 0) {
|
|
// Move several rules
|
|
$iterator3 = $DB->request($criteria);
|
|
while ($data = $iterator3->next()) {
|
|
$data['ranking'] += $diff;
|
|
$result = $rule->update($data);
|
|
}
|
|
} else {
|
|
// Only move one
|
|
$result = $rule->update([
|
|
'id' => $ID,
|
|
'ranking' => $new_rank
|
|
]);
|
|
}
|
|
|
|
// Update reference
|
|
if ($result) {
|
|
$result = $rule->update([
|
|
'id' => $other_ID,
|
|
'ranking' => $current_rank
|
|
]);
|
|
}
|
|
return $result;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Update Rule Order when deleting a rule
|
|
*
|
|
* @param $ranking rank of the deleted rule
|
|
*
|
|
* @return true if all ok
|
|
**/
|
|
function deleteRuleOrder($ranking) {
|
|
global $DB;
|
|
|
|
$result = $DB->update(
|
|
'glpi_rules', [
|
|
'ranking' => new \QueryExpression($DB->quoteName('ranking') . ' - 1')
|
|
], [
|
|
'sub_type' => $this->getRuleClassName(),
|
|
'ranking' => ['>', $ranking]
|
|
]
|
|
);
|
|
return $result;
|
|
}
|
|
|
|
|
|
/**
|
|
* Move a rule in an ordered collection
|
|
*
|
|
* @param $ID of the rule to move
|
|
* @param $ref_ID of the rule position (0 means all, so before all or after all)
|
|
* @param $type of move : after or before ( default 'after')
|
|
*
|
|
* @return true if all ok
|
|
**/
|
|
function moveRule($ID, $ref_ID, $type = 'after') {
|
|
global $DB;
|
|
|
|
$ruleDescription = new Rule();
|
|
|
|
// Get actual ranking of Rule to move
|
|
$ruleDescription->getFromDB($ID);
|
|
$old_rank = $ruleDescription->fields["ranking"];
|
|
|
|
// Compute new ranking
|
|
if ($ref_ID) { // Move after/before an existing rule
|
|
$ruleDescription->getFromDB($ref_ID);
|
|
$rank = $ruleDescription->fields["ranking"];
|
|
|
|
} else if ($type == "after") {
|
|
// Move after all
|
|
$result = $DB->request([
|
|
'SELECT' => ['MAX' => 'ranking AS maxi'],
|
|
'FROM' => 'glpi_rules',
|
|
'WHERE' => ['sub_type' => $this->getRuleClassName()]
|
|
])->next();
|
|
$rank = $result['maxi'];
|
|
} else {
|
|
// Move before all
|
|
$rank = 1;
|
|
}
|
|
|
|
$rule = $this->getRuleClass();
|
|
|
|
$result = false;
|
|
|
|
// Move others rules in the collection
|
|
if ($old_rank < $rank) {
|
|
if ($type == "before") {
|
|
$rank--;
|
|
}
|
|
|
|
// Move back all rules between old and new rank
|
|
$iterator = $DB->request([
|
|
'SELECT' => ['id', 'ranking'],
|
|
'FROM' => 'glpi_rules',
|
|
'WHERE' => [
|
|
'sub_type' => $this->getRuleClassName(),
|
|
['ranking' => ['>', $old_rank]],
|
|
['ranking' => ['<=', $rank]]
|
|
]
|
|
]);
|
|
while ($data = $iterator->next()) {
|
|
$data['ranking']--;
|
|
$result = $rule->update($data);
|
|
}
|
|
|
|
} else if ($old_rank > $rank) {
|
|
if ($type == "after") {
|
|
$rank++;
|
|
}
|
|
|
|
// Move forward all rule between old and new rank
|
|
$iterator = $DB->request([
|
|
'SELECT' => ['id', 'ranking'],
|
|
'FROM' => 'glpi_rules',
|
|
'WHERE' => [
|
|
'sub_type' => $this->getRuleClassName(),
|
|
['ranking' => ['=>', $rank]],
|
|
['ranking' => ['<', $old_rank]]
|
|
]
|
|
]);
|
|
while ($data = $iterator->next()) {
|
|
$data['ranking']++;
|
|
$result = $rule->update($data);
|
|
}
|
|
|
|
} else { // $old_rank == $rank : nothing to do
|
|
$result = false;
|
|
}
|
|
|
|
// Move the rule
|
|
if ($result
|
|
&& ($old_rank != $rank)) {
|
|
$result = $rule->update(['id' => $ID,
|
|
'ranking' => $rank]);
|
|
}
|
|
return ($result ? true : false);
|
|
}
|
|
|
|
|
|
/**
|
|
* Print a title for backup rules
|
|
*
|
|
* @since 0.85
|
|
*
|
|
* @return void
|
|
**/
|
|
static function titleBackup() {
|
|
global $CFG_GLPI;
|
|
|
|
$buttons = [];
|
|
$title = "";
|
|
|
|
$buttons["{$CFG_GLPI["root_doc"]}/front/rule.backup.php?action=import"] = _x('button', 'Import');
|
|
$buttons["{$CFG_GLPI["root_doc"]}/front/rule.backup.php?action=export"] = _x('button', 'Export');
|
|
|
|
echo "<div class='center'><table class='tab_glpi'><tr>";
|
|
echo "<td><i class='far fa-save fa-3x'></i></td>";
|
|
foreach ($buttons as $key => $val) {
|
|
echo "<td><a class='vsubmit' href='".$key."'>".$val."</a></td>";
|
|
}
|
|
echo "</tr></table></div>";
|
|
}
|
|
|
|
|
|
/**
|
|
* Export rules in a xml format
|
|
*
|
|
* @param items array the input data to transform to xml
|
|
*
|
|
* @since 0.85
|
|
*
|
|
* @return void send attachment to browser
|
|
**/
|
|
static function exportRulesToXML($items = []) {
|
|
|
|
if (!count($items)) {
|
|
return false;
|
|
}
|
|
|
|
$rulecollection = new self();
|
|
$rulecritera = new RuleCriteria();
|
|
$ruleaction = new RuleAction();
|
|
|
|
//create xml
|
|
$xmlE = new SimpleXMLElement('<rules/>');
|
|
|
|
//parse all rules
|
|
foreach ($items as $key => $ID) {
|
|
$rulecollection->getFromDB($ID);
|
|
if (!class_exists($rulecollection->fields['sub_type'])) {
|
|
continue;
|
|
}
|
|
$rule = new $rulecollection->fields['sub_type'];
|
|
unset($rulecollection->fields['id']);
|
|
unset($rulecollection->fields['date_mod']);
|
|
|
|
$name = Dropdown::getDropdownName("glpi_entities",
|
|
$rulecollection->fields['entities_id']);
|
|
$rulecollection->fields['entities_id'] = $name;
|
|
|
|
//add root node
|
|
$xmlERule = $xmlE->addChild('rule');
|
|
|
|
//convert rule direct indexes in XML
|
|
foreach ($rulecollection->fields as $key => $val) {
|
|
$xmlERule->$key = $val;
|
|
}
|
|
|
|
//find criterias
|
|
$criterias = $rulecritera->find(['rules_id' => $ID]);
|
|
foreach ($criterias as &$criteria) {
|
|
unset($criteria['id']);
|
|
unset($criteria['rules_id']);
|
|
|
|
$available_criteria = $rule->getCriterias();
|
|
$crit = $criteria['criteria'];
|
|
if (self::isCriteraADropdown($available_criteria, $criteria['condition'], $crit)) {
|
|
$criteria['pattern']
|
|
= Html::clean(Dropdown::getDropdownName($available_criteria[$crit]['table'],
|
|
$criteria['pattern']));
|
|
}
|
|
|
|
//convert criterias in XML
|
|
$xmlECritiera = $xmlERule->addChild('rulecriteria');
|
|
foreach ($criteria as $key => $val) {
|
|
$xmlECritiera->$key = $val;
|
|
}
|
|
}
|
|
|
|
//find actions
|
|
$actions = $ruleaction->find(['rules_id' => $ID]);
|
|
foreach ($actions as &$action) {
|
|
unset($action['id']);
|
|
unset($action['rules_id']);
|
|
|
|
//process FK (just in case of "assign" action)
|
|
if (($action['action_type'] == "assign")
|
|
&& (strpos($action['field'], '_id') !== false)
|
|
&& !(($action['field'] == "entities_id")
|
|
&& ($action['value'] == 0))) {
|
|
$field = $action['field'];
|
|
if ($action['field'][0] == "_") {
|
|
$field = substr($action['field'], 1);
|
|
}
|
|
$table = getTableNameForForeignKeyField($field);
|
|
|
|
$action['value'] = Html::clean(Dropdown::getDropdownName($table, $action['value']));
|
|
}
|
|
|
|
//convert actions in XML
|
|
$xmlEAction = $xmlERule->addChild('ruleaction');
|
|
foreach ($action as $key => $val) {
|
|
$xmlEAction->$key = $val;
|
|
}
|
|
}
|
|
}
|
|
|
|
//convert SimpleXMLElement to xml string
|
|
$xml = $xmlE->asXML();
|
|
|
|
//send attachment to browser
|
|
header('Content-type: application/xml');
|
|
header('Content-Disposition: attachment; filename="rules.xml"');
|
|
echo $xml;
|
|
|
|
//exit;
|
|
}
|
|
|
|
|
|
/**
|
|
* Print a form to select a xml file for import rules
|
|
*
|
|
* @since 0.85
|
|
*
|
|
* @return void
|
|
**/
|
|
static function displayImportRulesForm() {
|
|
|
|
echo "<form name='form' method='post' action='rule.backup.php' ".
|
|
"enctype='multipart/form-data' >";
|
|
echo "<div class='center'>";
|
|
|
|
echo "<h2>".__("Import rules from a XML file")."</h2>";
|
|
echo "<input type='file' name='xml_file'> ";
|
|
echo "<input type='hidden' name='action' value='preview_import'>";
|
|
echo "<input type='submit' name='import' value=\""._sx('button', 'Import').
|
|
"\" class='submit'>";
|
|
|
|
// Close for Form
|
|
echo "</div>";
|
|
Html::closeForm();
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
* Check if a criterion is a dropdown or not
|
|
*
|
|
* @since 0.85
|
|
*
|
|
* @param $available_criteria available criterai for this rule
|
|
* @param $condition the rulecriteria condition
|
|
* @param $criterion the criterion
|
|
*
|
|
* @return true if a criterion is a dropdown, false otherwise
|
|
**/
|
|
static function isCriteraADropdown($available_criteria, $condition, $criterion) {
|
|
|
|
if (isset($available_criteria[$criterion]['type'])) {
|
|
$type = $available_criteria[$criterion]['type'];
|
|
} else {
|
|
$type = false;
|
|
}
|
|
return (in_array($condition,
|
|
[Rule::PATTERN_IS, Rule::PATTERN_IS_NOT, Rule::PATTERN_UNDER])
|
|
&& ($type == 'dropdown'));
|
|
}
|
|
|
|
|
|
/**
|
|
* Print a form to inform user when conflicts appear during the import of rules from a xml file
|
|
*
|
|
* @since 0.85
|
|
*
|
|
* @return true if all ok
|
|
**/
|
|
static function previewImportRules() {
|
|
global $DB;
|
|
|
|
if (!isset($_FILES["xml_file"]) || ($_FILES["xml_file"]["size"] == 0)) {
|
|
return false;
|
|
}
|
|
|
|
if ($_FILES["xml_file"]["error"] != UPLOAD_ERR_OK) {
|
|
Session::addMessageAfterRedirect(__("No file was uploaded"));
|
|
return false;
|
|
}
|
|
//get xml file content
|
|
$xml = file_get_contents($_FILES["xml_file"]["tmp_name"]);
|
|
//convert a xml string into a SimpleXml object
|
|
if (!$xmlE= simplexml_load_string($xml)) {
|
|
Session::addMessageAfterRedirect(__('Unauthorized file type'), false, ERROR);
|
|
}
|
|
//convert SimpleXml object into an array and store it in session
|
|
$rules = json_decode(json_encode((array) $xmlE), true);
|
|
//check rules (check if entities, criterias and actions is always good in this glpi)
|
|
$entity = new Entity();
|
|
$rules_refused = [];
|
|
|
|
//In case there's only one rule to import, recreate an array with key => value
|
|
if (isset($rules['rule']['entities_id'])) {
|
|
$rules['rule'] = [0 => $rules['rule']];
|
|
}
|
|
|
|
foreach ($rules['rule'] as $k_rule => &$rule) {
|
|
$tmprule = new $rule['sub_type'];
|
|
//check entities
|
|
if ($tmprule->isEntityAssign()) {
|
|
$entities_found = $entity->find(['completename' => $rule['entities_id']]);
|
|
if (empty($entities_found)) {
|
|
$rules_refused[$k_rule]['entity'] = true;
|
|
}
|
|
}
|
|
|
|
//process direct attributes
|
|
foreach ($rule as &$val) {
|
|
if (is_array($val)
|
|
&& empty($val)) {
|
|
$val = "";
|
|
}
|
|
}
|
|
|
|
//check criterias
|
|
if (isset($rule['rulecriteria'])) {
|
|
//check and correct criterias array format
|
|
if (isset($rule['rulecriteria']['criteria'])) {
|
|
$rule['rulecriteria'] = [$rule['rulecriteria']];
|
|
}
|
|
|
|
foreach ($rule['rulecriteria'] as $k_crit => $criteria) {
|
|
$available_criteria = $tmprule->getCriterias();
|
|
$crit = $criteria['criteria'];
|
|
//check FK (just in case of "is", "is_not" and "under" criteria)
|
|
if (self::isCriteraADropdown($available_criteria,
|
|
$criteria['condition'], $crit)) {
|
|
//escape pattern
|
|
$criteria['pattern'] = $DB->escape(Html::entity_decode_deep($criteria['pattern']));
|
|
$itemtype = getItemTypeForTable($available_criteria[$crit]['table']);
|
|
$item = new $itemtype();
|
|
if ($item instanceof CommonTreeDropdown) {
|
|
$found = $item->find(['completename' => $criteria['pattern']]);
|
|
} else {
|
|
$found = $item->find(['name' => $criteria['pattern']]);
|
|
}
|
|
if (empty($found)) {
|
|
$rules_refused[$k_rule]['criterias'][] = $k_crit;
|
|
} else {
|
|
$tmp = array_pop($found);
|
|
$rules['rule'][$k_rule]['rulecriteria'][$k_crit]['pattern'] = $tmp['id'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//check actions
|
|
if (isset($rule['ruleaction'])) {
|
|
//check and correct actions array format
|
|
if (isset($rule['ruleaction']['field'])) {
|
|
$rule['ruleaction'] = [$rule['ruleaction']];
|
|
}
|
|
|
|
foreach ($rule['ruleaction'] as $k_action => $action) {
|
|
$available_actions = $tmprule->getActions();
|
|
$act = $action['field'];
|
|
|
|
if (($action['action_type'] == "assign")
|
|
&& (isset($available_actions[$act]['type'])
|
|
&& ($available_actions[$act]['type'] == 'dropdown'))) {
|
|
|
|
//pass root entity and empty array (N/A value)
|
|
if (($action['field'] == "entities_id")
|
|
&& (($action['value'] == 0)
|
|
|| ($action['value'] == []))) {
|
|
continue;
|
|
}
|
|
|
|
//escape value
|
|
$action['value'] = $DB->escape(Html::entity_decode_deep($action['value']));
|
|
$itemtype = getItemTypeForTable($available_actions[$act]['table']);
|
|
$item = new $itemtype();
|
|
if ($item instanceof CommonTreeDropdown) {
|
|
$found = $item->find(['completename' => $action['value']]);
|
|
} else {
|
|
$found = $item->find(['name' => $action['value']]);
|
|
}
|
|
if (empty($found)) {
|
|
$rules_refused[$k_rule]['actions'][] = $k_action;
|
|
} else {
|
|
$tmp = array_pop($found);
|
|
$rules['rule'][$k_rule]['ruleaction'][$k_action]['value'] = $tmp['id'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//save rules for ongoing processing
|
|
$_SESSION['glpi_import_rules'] = $rules;
|
|
$_SESSION['glpi_import_rules_refused'] = $rules_refused;
|
|
|
|
//if no conflict detected, we can directly process the import
|
|
if (!count($rules_refused)) {
|
|
Html::redirect("rule.backup.php?action=process_import");
|
|
}
|
|
|
|
//print report
|
|
echo "<form name='form' method='post' action='rule.backup.php' >";
|
|
echo "<div class='spaced' id='tabsbody'>";
|
|
echo "<table class='tab_cadre'>";
|
|
echo "<input type='hidden' name='action' value='process_import'>";
|
|
echo "<tr><th colspan='3'>".__('Rules refused')."</th></tr>";
|
|
echo "<tr>";
|
|
echo "<th>"._n('Type', 'Type', 1)."</th>";
|
|
echo "<th>".__('Name')."</th>";
|
|
echo "<th>".__('Reason of rejection')."</th>";
|
|
echo "</tr>";
|
|
|
|
$odd = true;
|
|
foreach ($rules_refused as $k_rule => $refused) {
|
|
$odd = !$odd;
|
|
if ($odd) {
|
|
$class = " class='tab_bg_1' ";
|
|
} else {
|
|
$class = " class='tab_bg_2' ";
|
|
}
|
|
|
|
$sub_type = $rules['rule'][$k_rule]['sub_type'];
|
|
$item = new $sub_type();
|
|
|
|
echo "<tr $class>";
|
|
echo "<td>".$item->getTitle()."</td>";
|
|
echo "<td>".$rules['rule'][$k_rule]['name']."</td>";
|
|
echo "<td>";
|
|
|
|
echo "<table class='tab_cadre' style='width:100%'>";
|
|
//show entity select
|
|
if (!isset($refused['criterias']) && !isset($refused['actions'])) {
|
|
if (isset($refused['entity'])) {
|
|
echo "<tr class='tab_bg_1_2'>";
|
|
echo "<td>";
|
|
printf(__('%1$s (%2$s)'), __('Entity not found'),
|
|
$rules['rule'][$k_rule]['entities_id']);
|
|
echo "</td>";
|
|
echo "<td>";
|
|
echo __('Select the desired entity')." ";
|
|
Dropdown::show('Entity',
|
|
['comments' => false,
|
|
'name' => "new_entities[".
|
|
$rules['rule'][$k_rule]['uuid']."]"]);
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
}
|
|
}
|
|
|
|
//show criterias refused for this rule
|
|
if (isset($refused['criterias'])) {
|
|
echo "<tr class='tab_bg_1_2'>";
|
|
echo "<td>".__('Criteria refused')."</td>";
|
|
echo "<td>";
|
|
|
|
echo "<table class='tab_cadre' style='width:100%'>";
|
|
echo "<tr class='tab_bg_2'>";
|
|
echo "<th class='center b'>"._n('Criterion', 'Criteria', 1)."</th>\n";
|
|
echo "<th class='center b'>".__('Condition')."</th>\n";
|
|
echo "<th class='center b'>".__('Reason')."</th>\n";
|
|
echo "</tr>\n";
|
|
foreach ($refused['criterias'] as $k_criteria) {
|
|
$criteria = $rules['rule'][$k_rule]['rulecriteria'][$k_criteria];
|
|
|
|
//fix empty empty array values
|
|
if (empty($criteria['value'])) {
|
|
$criteria['value'] = null;
|
|
}
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>" . $item->getCriteriaName($criteria["criteria"]) . "</td>";
|
|
echo "<td>" . RuleCriteria::getConditionByID($criteria["condition"],
|
|
get_class($item),
|
|
$criteria["criteria"]) . "</td>";
|
|
echo "<td>" . $criteria["pattern"]."</td>";
|
|
echo "</tr>";
|
|
}
|
|
echo "</table>\n";
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
}
|
|
|
|
//show actions refused for this rule
|
|
if (isset($refused['actions'])) {
|
|
echo "<tr class='tab_bg_1_2'>";
|
|
echo "<td>".__('Actions refused')."</td>";
|
|
echo "<td>";
|
|
|
|
echo "<table class='tab_cadre' style='width:100%'>";
|
|
echo "<tr class='tab_bg_2'>";
|
|
echo "<th class='center b'>"._n('Field', 'Fields', Session::getPluralNumber())."</th>";
|
|
echo "<th class='center b'>".__('Action type')."</th>";
|
|
echo "<th class='center b'>".__('Value')."</th>";
|
|
echo "</tr>\n";
|
|
foreach ($refused['actions'] as $k_action) {
|
|
$action = $rules['rule'][$k_rule]['ruleaction'][$k_action];
|
|
//fix empty empty array values
|
|
if (empty($action['value'])) {
|
|
$action['value'] = null;
|
|
}
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>" . $item->getActionName($action["field"]) . "</td>";
|
|
echo "<td>" . RuleAction::getActionByID($action["action_type"]) . "</td>";
|
|
echo "<td>" . $action["value"]."</td>";
|
|
echo "</tr>";
|
|
}
|
|
echo "</table>\n";
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
}
|
|
echo "</table>\n";
|
|
echo "</td></tr>";
|
|
}
|
|
|
|
//display buttons
|
|
$class = ($odd?" class='tab_bg_1' ":" class='tab_bg_2' ");
|
|
echo "<tr $class><td colspan='3' class='center'>";
|
|
echo "<input type='submit' name='import' value=\""._sx('button', 'Post').
|
|
"\" class='submit'>";
|
|
echo "</td></tr>";
|
|
|
|
// Close for Form
|
|
echo "</table></div>";
|
|
Html::closeForm();
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* import rules in glpi after user validation
|
|
*
|
|
* @since 0.85
|
|
*
|
|
* @return true if all ok
|
|
**/
|
|
static function processImportRules() {
|
|
$ruleCriteria = new RuleCriteria();
|
|
$ruleAction = new RuleAction();
|
|
$entity = new Entity();
|
|
|
|
//get session vars
|
|
$rules = $_SESSION['glpi_import_rules'];
|
|
$rules_refused = $_SESSION['glpi_import_rules_refused'];
|
|
$rr_keys = array_keys($rules_refused);
|
|
unset($_SESSION['glpi_import_rules']);
|
|
unset($_SESSION['glpi_import_rules_refused']);
|
|
|
|
// unset all refused rules
|
|
foreach ($rules['rule'] as $k_rule => &$rule) {
|
|
if (in_array($k_rule, $rr_keys)) {
|
|
//Do not process rule with actions or criterias refused
|
|
if (isset($rules_refused[$k_rule]['criterias'])
|
|
|| isset($rules_refused[$k_rule]['actions'])) {
|
|
unset($rules['rule'][$k_rule]);
|
|
} else {// accept rule with only entity not found (change entity)
|
|
$rule['entities_id'] = $_REQUEST['new_entities'][$rule['uuid']];
|
|
}
|
|
}
|
|
}
|
|
|
|
//import all right rules
|
|
while (!empty($rules['rule'])) {
|
|
$current_rule = array_shift($rules['rule']);
|
|
$add_criteria_and_actions = false;
|
|
$params = [];
|
|
$itemtype = $current_rule['sub_type'];
|
|
$item = new $itemtype();
|
|
|
|
//Find a rule by it's uuid
|
|
$found = $item->find(['uuid' => $current_rule['uuid']]);
|
|
$params = Toolbox::addslashes_deep($current_rule);
|
|
unset($params['rulecriteria']);
|
|
unset($params['ruleaction']);
|
|
|
|
if (!$item->isEntityAssign()) {
|
|
$params['entities_id'] = 0;
|
|
} else {
|
|
$entities_found = $entity->find(['completename' => $rule['entities_id']]);
|
|
if (!empty($entities_found)) {
|
|
$entity_found = array_shift($entities_found);
|
|
$params['entities_id'] = $entity_found['id'];
|
|
} else {
|
|
$params['entities_id'] = 0;
|
|
}
|
|
}
|
|
foreach (['is_recursive', 'is_active'] as $field) {
|
|
//Should not be necessary but without it there's an sql error...
|
|
if (!isset($params[$field]) || ($params[$field] == '')) {
|
|
$params[$field] = 0;
|
|
}
|
|
}
|
|
|
|
//if uuid not exist, create rule
|
|
if (empty($found)) {
|
|
//Manage entity
|
|
$params['_add'] = true;
|
|
$rules_id = $item->add($params);
|
|
if ($rules_id) {
|
|
Event::log($rules_id, "rules", 4, "setup",
|
|
sprintf(__('%1$s adds the item %2$s'), $_SESSION["glpiname"], $rules_id));
|
|
$add_criteria_and_actions = true;
|
|
}
|
|
} else { //if uuid exists, then update the rule
|
|
$tmp = array_shift($found);
|
|
$params['id'] = $tmp['id'];
|
|
$params['_update'] = true;
|
|
$rules_id = $tmp['id'];
|
|
if ($item->update($params)) {
|
|
Event::log($rules_id, "rules", 4, "setup",
|
|
sprintf(__('%s updates an item'), $_SESSION["glpiname"]));
|
|
|
|
//remove all dependent criterias and action
|
|
$ruleCriteria->deleteByCriteria(["rules_id" => $rules_id]);
|
|
$ruleAction->deleteByCriteria(["rules_id" => $rules_id]);
|
|
$add_criteria_and_actions = true;
|
|
}
|
|
}
|
|
|
|
if ($add_criteria_and_actions) {
|
|
//Add criteria
|
|
if (isset($current_rule['rulecriteria'])) {
|
|
foreach ($current_rule['rulecriteria'] as $criteria) {
|
|
$criteria['rules_id'] = $rules_id;
|
|
//fix array in value key
|
|
//(simplexml bug, empty xml node are converted in empty array instead of null)
|
|
if (is_array($criteria['pattern'])) {
|
|
$criteria['pattern'] = null;
|
|
}
|
|
$criteria = Toolbox::addslashes_deep($criteria);
|
|
$ruleCriteria->add($criteria);
|
|
}
|
|
}
|
|
|
|
//Add actions
|
|
if (isset($current_rule['ruleaction'])) {
|
|
foreach ($current_rule['ruleaction'] as $action) {
|
|
$action['rules_id'] = $rules_id;
|
|
//fix array in value key
|
|
//(simplexml bug, empty xml node are converted in empty array instead of null)
|
|
if (is_array($action['value'])) {
|
|
$action['value'] = null;
|
|
}
|
|
$action = Toolbox::addslashes_deep($action);
|
|
$ruleAction->add($action);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Session::addMessageAfterRedirect(__('Successful importation'));
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* Process all the rules collection
|
|
*
|
|
* @param input array the input data used to check criterias (need to be clean slashes)
|
|
* @param output array the initial ouput array used to be manipulate by actions (need to be clean slashes)
|
|
* @param params array parameters for all internal functions (need to be clean slashes)
|
|
* @param options array options :
|
|
* - condition : specific condition to limit rule list
|
|
* - only_criteria : only react on specific criteria
|
|
*
|
|
* @return the output array updated by actions (addslashes datas)
|
|
**/
|
|
function processAllRules($input = [], $output = [], $params = [], $options = []) {
|
|
|
|
$p['condition'] = 0;
|
|
$p['only_criteria'] = null;
|
|
|
|
if (is_array($options) && count($options)) {
|
|
foreach ($options as $key => $val) {
|
|
$p[$key] = $val;
|
|
}
|
|
}
|
|
|
|
// Get Collection datas
|
|
$this->getCollectionDatas(1, 1, $p['condition']);
|
|
$input = $this->prepareInputDataForProcessWithPlugins($input, $params);
|
|
$output["_no_rule_matches"] = true;
|
|
//Store rule type being processed (for plugins)
|
|
$params['rule_itemtype'] = $this->getRuleClassName();
|
|
|
|
if (count($this->RuleList->list)) {
|
|
foreach ($this->RuleList->list as $rule) {
|
|
//If the rule is active, process it
|
|
|
|
if ($rule->fields["is_active"]) {
|
|
$output["_rule_process"] = false;
|
|
$rule->process($input, $output, $params, $p);
|
|
|
|
if ($output["_rule_process"] && $this->stop_on_first_match) {
|
|
unset($output["_rule_process"]);
|
|
$output["_ruleid"] = $rule->fields["id"];
|
|
return Toolbox::addslashes_deep($output);
|
|
}
|
|
}
|
|
|
|
if ($this->use_output_rule_process_as_next_input) {
|
|
$output = $this->prepareInputDataForProcessWithPlugins($output, $params);
|
|
$input = $output;
|
|
}
|
|
}
|
|
}
|
|
|
|
return Toolbox::addslashes_deep($output);
|
|
}
|
|
|
|
|
|
/**
|
|
* Show form displaying results for rule collection preview
|
|
*
|
|
* @param $target where to go
|
|
* @param $values array of data
|
|
* @param $condition condition to limit rules (default 0)
|
|
**/
|
|
function showRulesEnginePreviewCriteriasForm($target, array $values, $condition = 0) {
|
|
$input = $this->prepareInputDataForTestProcess($condition);
|
|
|
|
if (count($input)) {
|
|
$rule = $this->getRuleClass();
|
|
$criterias = $rule->getAllCriteria();
|
|
echo "<form name='testrule_form' id='testrulesengine_form' method='post' action='$target'>";
|
|
echo "\n<div class='center'>";
|
|
echo "<table class='tab_cadre_fixe'>";
|
|
echo "<tr><th colspan='2'>" . _n('Criterion', 'Criteria', Session::getPluralNumber()) . "</th></tr>\n";
|
|
|
|
//Brower all criterias
|
|
foreach ($input as $criteria) {
|
|
echo "<tr class='tab_bg_1'>";
|
|
|
|
if (isset($criterias[$criteria])) {
|
|
$criteria_constants = $criterias[$criteria];
|
|
echo "<td>".$criteria_constants["name"]."</td>";
|
|
} else {
|
|
echo "<td>".$criteria."</td>";
|
|
}
|
|
|
|
echo "<td>";
|
|
$rule->displayCriteriaSelectPattern($criteria, $criteria, Rule::PATTERN_IS,
|
|
isset($values[$criteria])?$values[$criteria]:'');
|
|
echo "</td></tr>\n";
|
|
}
|
|
|
|
// Add all used criteria on rule as `Rule::showSpecificCriteriasForPreview()`
|
|
// adapt its output depending on used criteria
|
|
$rule->criterias = [];
|
|
foreach ($input as $criteria) {
|
|
$rule->criterias[] = (object)[
|
|
'fields' => ['criteria' => $criteria],
|
|
];
|
|
}
|
|
$rule->showSpecificCriteriasForPreview($_POST);
|
|
|
|
echo "<tr><td class='tab_bg_2 center' colspan='2'>";
|
|
echo "<input type='submit' name='test_all_rules' value='". _sx('button', 'Test')."'
|
|
class='submit'>";
|
|
echo "<input type='hidden' name='sub_type' value='" . $this->getRuleClassName() . "'>";
|
|
echo "<input type='hidden' name='condition' value='$condition'>";
|
|
echo "</td></tr>\n";
|
|
echo "</table></div>";
|
|
Html::closeForm();
|
|
|
|
} else {
|
|
echo '<br><div class="center b">'.__('No element to be tested').'</div>';
|
|
}
|
|
|
|
return $input;
|
|
}
|
|
|
|
|
|
/**
|
|
* Test all the rules collection
|
|
*
|
|
* @param input array the input data used to check criterias
|
|
* @param output array the initial ouput array used to be manipulate by actions
|
|
* @param params array parameters for all internal functions
|
|
* @param $condition condition to limit rules (DEFAULT 0)
|
|
*
|
|
* @return the output array updated by actions
|
|
**/
|
|
function testAllRules($input = [], $output = [], $params = [], $condition = 0) {
|
|
|
|
// Get Collection data
|
|
$this->getCollectionDatas(1, 1, $condition);
|
|
|
|
$output["_no_rule_matches"] = true;
|
|
|
|
if (count($this->RuleList->list)) {
|
|
foreach ($this->RuleList->list as $rule) {
|
|
//If the rule is active, process it
|
|
if ($rule->fields["is_active"]) {
|
|
$output["_rule_process"] = false;
|
|
$output["result"][$rule->fields["id"]]["id"] = $rule->fields["id"];
|
|
$rule->process($input, $output, $params);
|
|
|
|
if ($output["_rule_process"]
|
|
&& $this->stop_on_first_match) {
|
|
unset($output["_rule_process"]);
|
|
$output["result"][$rule->fields["id"]]["result"] = 1;
|
|
$output["_ruleid"] = $rule->fields["id"];
|
|
return $output;
|
|
|
|
} else if ($output["_rule_process"]) {
|
|
$output["result"][$rule->fields["id"]]["result"] = 1;
|
|
|
|
} else {
|
|
$output["result"][$rule->fields["id"]]["result"] = 0;
|
|
}
|
|
|
|
} else {
|
|
//Rule is inactive
|
|
$output["result"][$rule->fields["id"]]["result"] = 2;
|
|
}
|
|
|
|
if ($this->use_output_rule_process_as_next_input) {
|
|
$input = $output;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
|
|
/**
|
|
* Prepare input datas for the rules collection
|
|
*
|
|
* @param $input the input data used to check criterias
|
|
* @param $params parameters
|
|
*
|
|
* @return the updated input datas
|
|
**/
|
|
function prepareInputDataForProcess($input, $params) {
|
|
return $input;
|
|
}
|
|
|
|
|
|
/**
|
|
* Prepare input datas for the rules collection, also using plugins values
|
|
*
|
|
* @since 0.84
|
|
*
|
|
* @param $input the input data used to check criterias
|
|
* @param $params parameters
|
|
*
|
|
* @return the updated input datas
|
|
**/
|
|
function prepareInputDataForProcessWithPlugins($input, $params) {
|
|
global $PLUGIN_HOOKS;
|
|
|
|
$input = $this->prepareInputDataForProcess($input, $params);
|
|
if (isset($PLUGIN_HOOKS['use_rules'])) {
|
|
foreach ($PLUGIN_HOOKS['use_rules'] as $plugin => $val) {
|
|
if (!Plugin::isPluginActive($plugin)) {
|
|
continue;
|
|
}
|
|
if (is_array($val) && in_array($this->getRuleClassName(), $val)) {
|
|
$results = Plugin::doOneHook($plugin, 'ruleCollectionPrepareInputDataForProcess',
|
|
['rule_itemtype' => $this->getRuleClassName(),
|
|
'values' => ['input' => $input,
|
|
'params' => $params]]);
|
|
if (is_array($results)) {
|
|
foreach ($results as $id => $result) {
|
|
$input[$id] = $result;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $input;
|
|
}
|
|
|
|
|
|
/**
|
|
* Prepare input datas for the rules collection
|
|
*
|
|
* @param $condition condition to limit rules (DEFAULT 0)
|
|
*
|
|
* @return the updated input datas
|
|
**/
|
|
function prepareInputDataForTestProcess($condition = 0) {
|
|
global $DB;
|
|
|
|
$limit = [];
|
|
if ($condition > 0) {
|
|
$limit = ['glpi_rules.condition' => ['&', (int)$condition]];
|
|
}
|
|
$input = [];
|
|
|
|
$iterator = $DB->request([
|
|
'SELECT' => 'glpi_rulecriterias.criteria',
|
|
'DISTINCT' => true,
|
|
'FROM' => 'glpi_rulecriterias',
|
|
'INNER JOIN' => [
|
|
'glpi_rules' => [
|
|
'ON' => [
|
|
'glpi_rulecriterias' => 'rules_id',
|
|
'glpi_rules' => 'id'
|
|
]
|
|
]
|
|
],
|
|
'WHERE' => [
|
|
'glpi_rules.is_active' => 1,
|
|
'glpi_rules.sub_type' => $this->getRuleClassName()
|
|
] + $limit
|
|
]);
|
|
|
|
while ($data = $iterator->next()) {
|
|
$input[] = $data["criteria"];
|
|
}
|
|
return $input;
|
|
}
|
|
|
|
|
|
/**
|
|
* Show form displaying results for rule engine preview
|
|
*
|
|
* @param $target where to go
|
|
* @param $input array of data
|
|
* @param $condition condition to limit rules (DEFAULT 0)
|
|
**/
|
|
function showRulesEnginePreviewResultsForm($target, array $input, $condition = 0) {
|
|
|
|
$output = [];
|
|
|
|
if ($this->use_output_rule_process_as_next_input) {
|
|
$output = $input;
|
|
}
|
|
|
|
$output = $this->testAllRules($input, $output, $input, $condition);
|
|
|
|
$rule = $this->getRuleClass();
|
|
|
|
echo "<div class='center'>";
|
|
|
|
if (isset($output["result"])) {
|
|
echo "<table class='tab_cadrehov'>";
|
|
echo "<tr><th colspan='2'>" . __('Result details') . "</th></tr>\n";
|
|
|
|
foreach ($output["result"] as $ID=>$rule_result) {
|
|
echo "<tr class='tab_bg_1'>";
|
|
$rule->getFromDB($ID);
|
|
echo "<td>".$rule->fields["name"]."</td>";
|
|
echo "<td class='b'>";
|
|
|
|
switch ($rule_result["result"]) {
|
|
case 0 :
|
|
case 1 :
|
|
echo Dropdown::getYesNo($rule_result["result"]);
|
|
break;
|
|
|
|
case 2 :
|
|
echo __('Inactive');
|
|
break;
|
|
}
|
|
|
|
echo "</td></tr>\n";
|
|
}
|
|
|
|
echo "</table>";
|
|
}
|
|
|
|
$output = $this->cleanTestOutputCriterias($output);
|
|
unset($output["result"]);
|
|
$global_result = (count($output)?1:0);
|
|
|
|
echo "<br><table class='tab_cadrehov'>";
|
|
$this->showTestResults($rule, $output, $global_result);
|
|
echo "</table></div>";
|
|
}
|
|
|
|
|
|
/**
|
|
* Unset criterias from the rule's ouput results (begins by _)
|
|
*
|
|
* @param $output array clean output array to clean
|
|
*
|
|
* @return cleaned array
|
|
**/
|
|
function cleanTestOutputCriterias(array $output) {
|
|
|
|
$rule = $this->getRuleClass();
|
|
$actions = $rule->getAllActions();
|
|
|
|
//If output array contains keys begining with _ : drop it
|
|
foreach ($output as $criteria => $value) {
|
|
if ($criteria[0] == '_'&& !isset($actions[$criteria])) {
|
|
unset($output[$criteria]);
|
|
}
|
|
}
|
|
return $output;
|
|
}
|
|
|
|
|
|
/**
|
|
* Show test results for a rule
|
|
*
|
|
* @param $rule rule object
|
|
* @param $output array output data array
|
|
* @param $global_result boolean global result
|
|
*
|
|
* @return cleaned array
|
|
**/
|
|
function showTestResults($rule, array $output, $global_result) {
|
|
|
|
$actions = $rule->getAllActions();
|
|
echo "<table class='tab_cadrehov'>";
|
|
echo "<tr><th colspan='2'>" . __('Rule results') . "</th></tr>\n";
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td class='center'>"._n('Validation', 'Validations', 1)."</td>";
|
|
echo "<td><span class='b'>".Dropdown::getYesNo($global_result)."</span></td>";
|
|
|
|
$output = $this->preProcessPreviewResults($output);
|
|
|
|
foreach ($output as $criteria => $value) {
|
|
if (isset($actions[$criteria])) {
|
|
echo "<tr class='tab_bg_2'>";
|
|
echo "<td>".$actions[$criteria]["name"]."</td>";
|
|
$action_type = (isset($actions[$criteria]['action_type'])?$actions[$criteria]['action_type']:'');
|
|
echo "<td>".$rule->getActionValue($criteria, $action_type, $value);
|
|
echo "</td></tr>\n";
|
|
}
|
|
}
|
|
echo "</tr></table>\n";
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $output
|
|
**/
|
|
function preProcessPreviewResults($output) {
|
|
global $PLUGIN_HOOKS;
|
|
|
|
if (isset($PLUGIN_HOOKS['use_rules'])) {
|
|
$params['rule_itemtype'] = $this->getType();
|
|
foreach ($PLUGIN_HOOKS['use_rules'] as $plugin => $val) {
|
|
if (!Plugin::isPluginActive($plugin)) {
|
|
continue;
|
|
}
|
|
if (is_array($val) && in_array($this->getType(), $val)) {
|
|
$results = Plugin::doOneHook($plugin, "preProcessRuleCollectionPreviewResults",
|
|
['output' => $output,
|
|
'params' => $params]);
|
|
if (is_array($results)) {
|
|
foreach ($results as $id => $result) {
|
|
$output[$id] = $result;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $this->cleanTestOutputCriterias($output);
|
|
}
|
|
|
|
|
|
/**
|
|
* Print a title if needed which will be displayed above list of rules
|
|
*
|
|
* @return void
|
|
**/
|
|
function title() {
|
|
}
|
|
|
|
|
|
/**
|
|
* Get rulecollection classname by giving his itemtype
|
|
*
|
|
* @param $itemtype itemtype
|
|
* @param $check_dictionnary_type check if the itemtype is a dictionnary or not
|
|
* (false by default)
|
|
*
|
|
* @return the rulecollection class or null
|
|
*/
|
|
static function getClassByType($itemtype, $check_dictionnary_type = false) {
|
|
global $CFG_GLPI;
|
|
|
|
if ($plug = isPluginItemType($itemtype)) {
|
|
$typeclass = 'Plugin'.$plug['plugin'].$plug['class'].'Collection';
|
|
|
|
} else {
|
|
if (in_array($itemtype, $CFG_GLPI["dictionnary_types"])) {
|
|
$typeclass = 'RuleDictionnary'.$itemtype."Collection";
|
|
} else {
|
|
$typeclass = $itemtype."Collection";
|
|
}
|
|
}
|
|
|
|
if (($check_dictionnary_type && in_array($itemtype, $CFG_GLPI["dictionnary_types"]))
|
|
|| !$check_dictionnary_type) {
|
|
|
|
if ($item = getItemForItemtype($typeclass)) {
|
|
return $item;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
function showInheritedTab() {
|
|
return false;
|
|
}
|
|
|
|
|
|
function showChildrensTab() {
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get all the fields needed to perform the rule
|
|
**/
|
|
function getFieldsToLookFor() {
|
|
global $DB;
|
|
|
|
$params = [];
|
|
|
|
$iterator = $DB->request([
|
|
'SELECT' => 'glpi_rulecriterias.criteria',
|
|
'DISTINCT' => true,
|
|
'FROM' => 'glpi_rulecriterias',
|
|
'INNER JOIN' => [
|
|
'glpi_rules' => [
|
|
'ON' => [
|
|
'glpi_rulecriterias' => 'rules_id',
|
|
'glpi_rules' => 'id'
|
|
]
|
|
]
|
|
],
|
|
'WHERE' => [
|
|
'glpi_rules.is_active' => 1,
|
|
'glpi_rules.sub_type' => $this->getRuleClassName()
|
|
]
|
|
]);
|
|
|
|
while ($data = $iterator->next()) {
|
|
$params[] = Toolbox::strtolower($data["criteria"]);
|
|
}
|
|
return $params;
|
|
}
|
|
|
|
|
|
/**
|
|
* For tabs management : force isNewItem
|
|
*
|
|
* @since 0.83
|
|
**/
|
|
function isNewItem() {
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* @see CommonGLPI::defineTabs()
|
|
**/
|
|
function defineTabs($options = []) {
|
|
|
|
$ong = [];
|
|
$this->addStandardTab(__CLASS__, $ong, $options);
|
|
$ong['no_all_tab'] = true;
|
|
return $ong;
|
|
}
|
|
|
|
|
|
/**
|
|
* @see CommonGLPI::getTabNameForItem()
|
|
**/
|
|
function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) {
|
|
|
|
if ($item instanceof RuleCollection) {
|
|
$ong = [];
|
|
if ($item->showInheritedTab()) {
|
|
//TRANS: %s is the entity name
|
|
$ong[1] = sprintf(__('Rules applied: %s'),
|
|
Dropdown::getDropdownName('glpi_entities',
|
|
$_SESSION['glpiactive_entity']));
|
|
}
|
|
$title = _n('Rule', 'Rules', Session::getPluralNumber());
|
|
if ($item->isRuleRecursive()) {
|
|
//TRANS: %s is the entity name
|
|
$title = sprintf(__('Local rules: %s'),
|
|
Dropdown::getDropdownName('glpi_entities',
|
|
$_SESSION['glpiactive_entity']));
|
|
}
|
|
$ong[2] = $title;
|
|
if ($item->showChildrensTab()) {
|
|
$ong[3] = __('Rules applicable in the sub-entities');
|
|
}
|
|
return $ong;
|
|
}
|
|
return '';
|
|
}
|
|
|
|
|
|
static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) {
|
|
|
|
if ($item instanceof RuleCollection) {
|
|
$options = $_GET;
|
|
switch ($tabnum) {
|
|
case 1:
|
|
$options['inherited'] = 1;
|
|
break;
|
|
|
|
case 2:
|
|
$options['inherited'] = 0;
|
|
break;
|
|
|
|
case 3 :
|
|
$options['inherited'] = 0;
|
|
$options['childrens'] = 1;
|
|
break;
|
|
}
|
|
if ($item->isRuleEntityAssigned()) {
|
|
$item->setEntity($_SESSION['glpiactive_entity']);
|
|
}
|
|
$item->title();
|
|
$item->showEngineSummary();
|
|
$item->showListRules($_GET['_target'], $options);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get list of dictionnaries
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function getDictionnaries() {
|
|
$dictionnaries =[];
|
|
|
|
$entries = [];
|
|
|
|
if (Session::haveRight("rule_dictionnary_software", READ)) {
|
|
$entries[] = [
|
|
'label' => _n('Software', 'Software', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnarysoftware.php'
|
|
];
|
|
}
|
|
|
|
if (Session::haveRight("rule_dictionnary_dropdown", READ)) {
|
|
$entries[] = [
|
|
'label' => _n('Manufacturer', 'Manufacturers', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnarymanufacturer.php'
|
|
];
|
|
}
|
|
|
|
if (Session::haveRight("rule_dictionnary_printer", READ)) {
|
|
$entries[] = [
|
|
'label' => _n('Printer', 'Printers', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnaryprinter.php'
|
|
];
|
|
}
|
|
|
|
if (count($entries)) {
|
|
$dictionnaries[] = [
|
|
'type' => __('Global dictionary'),
|
|
'entries' => $entries
|
|
];
|
|
}
|
|
|
|
if (Session::haveRight("rule_dictionnary_dropdown", READ)) {
|
|
$dictionnaries[] = [
|
|
'type' => _n('Model', 'Models', Session::getPluralNumber()),
|
|
'entries' => [
|
|
[
|
|
'label' => _n('Computer model', 'Computer models', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnarycomputermodel.php'
|
|
], [
|
|
'label' => _n('Monitor model', 'Monitor models', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnarymonitormodel.php'
|
|
], [
|
|
'label' => _n('Printer model', 'Printer models', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnaryprintermodel.php'
|
|
], [
|
|
'label' => _n('Device model', 'Device models', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnaryperipheralmodel.php'
|
|
], [
|
|
'label' => _n('Network equipment model', 'Network equipment models', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnarynetworkequipmentmodel.php'
|
|
], [
|
|
'label' => _n('Phone model', 'Phone models', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnaryphonemodel.php'
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
if (Session::haveRight("rule_dictionnary_dropdown", READ)) {
|
|
$dictionnaries[] = [
|
|
'type' => _n('Type', 'Types', Session::getPluralNumber()),
|
|
'entries' => [
|
|
[
|
|
'label' => _n('Computer type', 'Computer types', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnarycomputertype.php'
|
|
], [
|
|
'label' => _n('Monitor type', 'Monitor types', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnarymonitortype.php'
|
|
], [
|
|
'label' => _n('Printer type', 'Printer types', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnaryprintertype.php'
|
|
], [
|
|
'label' => _n('Device type', 'Device types', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnaryperipheraltype.php'
|
|
], [
|
|
'label' => _n('Network equipment type', 'Network equipment types', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnarynetworkequipmenttype.php'
|
|
], [
|
|
'label' => _n('Phone type', 'Phone types', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnaryphonetype.php'
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
if (Session::haveRight("rule_dictionnary_dropdown", READ)) {
|
|
$dictionnaries[] = [
|
|
'type' => OperatingSystem::getTypeName(Session::getPluralNumber()),
|
|
'entries' => [
|
|
[
|
|
'label' => OperatingSystem::getTypeName(Session::getPluralNumber()),
|
|
'link' => 'ruledictionnaryoperatingsystem.php'
|
|
], [
|
|
'label' => _n('Service pack', 'Service packs', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnaryoperatingsystemservicepack.php'
|
|
], [
|
|
'label' => _n('Version', 'Versions', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnaryoperatingsystemversion.php'
|
|
], [
|
|
'label' => _n('Architecture', 'Architectures', Session::getPluralNumber()),
|
|
'link' => 'ruledictionnaryoperatingsystemarchitecture.php'
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
return $dictionnaries;
|
|
}
|
|
}
|