Files
MYSOPHAL/inc/rulecollection.class.php
2025-08-07 13:15:31 +01:00

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'>&nbsp;</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'>&nbsp;</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'>&nbsp;";
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')."&nbsp;";
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;
}
}