3192 lines
107 KiB
PHP
3192 lines
107 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/>.
|
|
* ---------------------------------------------------------------------
|
|
*/
|
|
|
|
if (!defined('GLPI_ROOT')) {
|
|
die("Sorry. You can't access this file directly");
|
|
}
|
|
|
|
|
|
/**
|
|
* Rule Class store all information about a GLPI rule :
|
|
* - description
|
|
* - criterias
|
|
* - actions
|
|
**/
|
|
class Rule extends CommonDBTM {
|
|
use Glpi\Features\Clonable;
|
|
|
|
public $dohistory = true;
|
|
|
|
// Specific ones
|
|
///Actions affected to this rule
|
|
public $actions = [];
|
|
///Criterias affected to this rule
|
|
public $criterias = [];
|
|
/// Rules can be sorted ?
|
|
public $can_sort = false;
|
|
/// field used to order rules
|
|
public $orderby = 'ranking';
|
|
|
|
/// restrict matching to self::AND_MATCHING or self::OR_MATCHING : specify value to activate
|
|
public $restrict_matching = false;
|
|
|
|
protected $rules_id_field = 'rules_id';
|
|
protected $ruleactionclass = 'RuleAction';
|
|
protected $rulecriteriaclass = 'RuleCriteria';
|
|
|
|
public $specific_parameters = false;
|
|
|
|
public $regex_results = [];
|
|
public $criterias_results = [];
|
|
|
|
static $rightname = 'config';
|
|
|
|
const RULE_NOT_IN_CACHE = -1;
|
|
const RULE_WILDCARD = '*';
|
|
|
|
//Generic rules engine
|
|
const PATTERN_IS = 0;
|
|
const PATTERN_IS_NOT = 1;
|
|
const PATTERN_CONTAIN = 2;
|
|
const PATTERN_NOT_CONTAIN = 3;
|
|
const PATTERN_BEGIN = 4;
|
|
const PATTERN_END = 5;
|
|
const REGEX_MATCH = 6;
|
|
const REGEX_NOT_MATCH = 7;
|
|
const PATTERN_EXISTS = 8;
|
|
const PATTERN_DOES_NOT_EXISTS = 9;
|
|
const PATTERN_FIND = 10; // Global criteria
|
|
const PATTERN_UNDER = 11;
|
|
const PATTERN_NOT_UNDER = 12;
|
|
const PATTERN_IS_EMPTY = 30; // Global criteria
|
|
|
|
const AND_MATCHING = "AND";
|
|
const OR_MATCHING = "OR";
|
|
|
|
|
|
public function getCloneRelations() :array {
|
|
return [
|
|
RuleAction::class,
|
|
RuleCriteria::class
|
|
];
|
|
}
|
|
|
|
|
|
static function getTable($classname = null) {
|
|
return parent::getTable(__CLASS__);
|
|
}
|
|
|
|
|
|
static function getTypeName($nb = 0) {
|
|
return _n('Rule', 'Rules', $nb);
|
|
}
|
|
|
|
|
|
/**
|
|
* Get correct Rule object for specific rule
|
|
*
|
|
* @since 0.84
|
|
*
|
|
* @param $rules_id ID of the rule
|
|
**/
|
|
static function getRuleObjectByID($rules_id) {
|
|
|
|
$rule = new self();
|
|
if ($rule->getFromDB($rules_id)) {
|
|
$realrule = new $rule->fields['sub_type']();
|
|
return $realrule;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Get condition array for rule. If empty array no condition used
|
|
* maybe overridden to define conditions using binary combination :
|
|
* example array(1 => Condition1,
|
|
* 2 => Condition2,
|
|
* 3 => Condition1&Condition2)
|
|
*
|
|
* @since 0.85
|
|
*
|
|
* @return array of conditions
|
|
**/
|
|
static function getConditionsArray() {
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Is this rule use condition
|
|
*
|
|
**/
|
|
function useConditions() {
|
|
return (count($this->getConditionsArray()) > 0);
|
|
}
|
|
|
|
/**
|
|
* Display a dropdown with all the rule conditions
|
|
*
|
|
* @since 0.85
|
|
*
|
|
* @param $options array of parameters
|
|
**/
|
|
static function dropdownConditions($options = []) {
|
|
|
|
$p['name'] = 'condition';
|
|
$p['value'] = 0;
|
|
$p['display'] = true;
|
|
$p['on_change'] = '';
|
|
|
|
if (is_array($options) && count($options)) {
|
|
foreach ($options as $key => $val) {
|
|
$p[$key] = $val;
|
|
}
|
|
}
|
|
$elements = static::getConditionsArray();
|
|
if (count($elements)) {
|
|
return Dropdown::showFromArray($p['name'], $elements, $p);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get rule condition type Name
|
|
*
|
|
* @param $value condition ID
|
|
**/
|
|
static function getConditionName($value) {
|
|
|
|
$cond = static::getConditionsArray();
|
|
|
|
if (isset($cond[$value])) {
|
|
return $cond[$value];
|
|
}
|
|
|
|
return NOT_AVAILABLE;
|
|
}
|
|
|
|
/**
|
|
* @see CommonGLPI::getMenuContent()
|
|
*
|
|
* @since 0.85
|
|
**/
|
|
static function getMenuContent() {
|
|
global $CFG_GLPI;
|
|
|
|
$menu = [];
|
|
|
|
if (Session::haveRight("rule_ldap", READ)
|
|
|| Session::haveRight("rule_import", READ)
|
|
|| Session::haveRight("rule_ticket", READ)
|
|
|| Session::haveRight("rule_softwarecategories", READ)
|
|
|| Session::haveRight("rule_mailcollector", READ)) {
|
|
|
|
$menu['rule']['title'] = static::getTypeName(Session::getPluralNumber());
|
|
$menu['rule']['page'] = static::getSearchURL(false);
|
|
$menu['rule']['icon'] = static::getIcon();
|
|
|
|
foreach ($CFG_GLPI["rulecollections_types"] as $rulecollectionclass) {
|
|
$rulecollection = new $rulecollectionclass();
|
|
if ($rulecollection->canList()) {
|
|
$ruleclassname = $rulecollection->getRuleClassName();
|
|
$menu['rule']['options'][$rulecollection->menu_option]['title']
|
|
= $rulecollection->getRuleClass()->getTitle();
|
|
$menu['rule']['options'][$rulecollection->menu_option]['page']
|
|
= $ruleclassname::getSearchURL(false);
|
|
$menu['rule']['options'][$rulecollection->menu_option]['links']['search']
|
|
= $ruleclassname::getSearchURL(false);
|
|
if ($rulecollection->canCreate()) {
|
|
$menu['rule']['options'][$rulecollection->menu_option]['links']['add']
|
|
= $ruleclassname::getFormURL(false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Transfer::canView()
|
|
&& Session::isMultiEntitiesMode()) {
|
|
|
|
$menu['rule']['title'] = static::getTypeName(Session::getPluralNumber());
|
|
$menu['rule']['page'] = static::getSearchURL(false);
|
|
$menu['rule']['icon'] = static::getIcon();
|
|
|
|
$menu['rule']['options']['transfer']['title'] = __('Transfer');
|
|
$menu['rule']['options']['transfer']['page'] = "/front/transfer.php";
|
|
$menu['rule']['options']['transfer']['links']['search'] = "/front/transfer.php";
|
|
|
|
if (Session::haveRightsOr("transfer", [CREATE, UPDATE])) {
|
|
$menu['rule']['options']['transfer']['links']['summary']
|
|
= "/front/transfer.action.php";
|
|
$menu['rule']['options']['transfer']['links']['add'] = Transfer::getFormURL(false);
|
|
}
|
|
}
|
|
|
|
if (Session::haveRight("rule_dictionnary_dropdown", READ)
|
|
|| Session::haveRight("rule_dictionnary_software", READ)
|
|
|| Session::haveRight("rule_dictionnary_printer", READ)) {
|
|
|
|
$menu['dictionnary']['title'] = _n('Dictionary', 'Dictionaries', Session::getPluralNumber());
|
|
$menu['dictionnary']['shortcut'] = '';
|
|
$menu['dictionnary']['page'] = '/front/dictionnary.php';
|
|
$menu['dictionnary']['icon'] = static::getIcon();
|
|
|
|
$menu['dictionnary']['options']['manufacturers']['title']
|
|
= _n('Manufacturer', 'Manufacturers', Session::getPluralNumber());
|
|
$menu['dictionnary']['options']['manufacturers']['page']
|
|
= '/front/ruledictionnarymanufacturer.php';
|
|
$menu['dictionnary']['options']['manufacturers']['links']['search']
|
|
= '/front/ruledictionnarymanufacturer.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['manufacturers']['links']['add']
|
|
= '/front/ruledictionnarymanufacturer.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['software']['title']
|
|
= _n('Software', 'Software', Session::getPluralNumber());
|
|
$menu['dictionnary']['options']['software']['page']
|
|
= '/front/ruledictionnarysoftware.php';
|
|
$menu['dictionnary']['options']['software']['links']['search']
|
|
= '/front/ruledictionnarysoftware.php';
|
|
|
|
if (RuleDictionnarySoftware::canCreate()) {
|
|
$menu['dictionnary']['options']['software']['links']['add']
|
|
= '/front/ruledictionnarysoftware.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['model.computer']['title']
|
|
= _n('Computer model', 'Computer models', Session::getPluralNumber());
|
|
$menu['dictionnary']['options']['model.computer']['page']
|
|
= '/front/ruledictionnarycomputermodel.php';
|
|
$menu['dictionnary']['options']['model.computer']['links']['search']
|
|
= '/front/ruledictionnarycomputermodel.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['model.computer']['links']['add']
|
|
= '/front/ruledictionnarycomputermodel.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['model.monitor']['title']
|
|
= _n('Monitor model', 'Monitor models', Session::getPluralNumber());
|
|
$menu['dictionnary']['options']['model.monitor']['page']
|
|
= '/front/ruledictionnarymonitormodel.php';
|
|
$menu['dictionnary']['options']['model.monitor']['links']['search']
|
|
= '/front/ruledictionnarymonitormodel.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['model.monitor']['links']['add']
|
|
= '/front/ruledictionnarymonitormodel.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['model.printer']['title']
|
|
= _n('Printer model', 'Printer models', Session::getPluralNumber());
|
|
$menu['dictionnary']['options']['model.printer']['page']
|
|
= '/front/ruledictionnaryprintermodel.php';
|
|
$menu['dictionnary']['options']['model.printer']['links']['search']
|
|
= '/front/ruledictionnaryprintermodel.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['model.printer']['links']['add']
|
|
= '/front/ruledictionnaryprintermodel.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['model.peripheral']['title']
|
|
= _n('Peripheral model', 'Peripheral models', Session::getPluralNumber());
|
|
$menu['dictionnary']['options']['model.peripheral']['page']
|
|
= '/front/ruledictionnaryperipheralmodel.php';
|
|
$menu['dictionnary']['options']['model.peripheral']['links']['search']
|
|
= '/front/ruledictionnaryperipheralmodel.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['model.peripheral']['links']['add']
|
|
= '/front/ruledictionnaryperipheralmodel.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['model.networking']['title']
|
|
= _n('Networking equipment model', 'Networking equipment models', Session::getPluralNumber());
|
|
$menu['dictionnary']['options']['model.networking']['page']
|
|
= '/front/ruledictionnarynetworkequipmentmodel.php';
|
|
$menu['dictionnary']['options']['model.networking']['links']['search']
|
|
= '/front/ruledictionnarynetworkequipmentmodel.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['model.networking']['links']['add']
|
|
= '/front/ruledictionnarynetworkequipmentmodel.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['model.phone']['title']
|
|
= _n('Phone model', 'Phone models', Session::getPluralNumber());
|
|
$menu['dictionnary']['options']['model.phone']['page']
|
|
= '/front/ruledictionnaryphonemodel.php';
|
|
$menu['dictionnary']['options']['model.phone']['links']['search']
|
|
= '/front/ruledictionnaryphonemodel.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['model.phone']['links']['add']
|
|
= '/front/ruledictionnaryphonemodel.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['type.computer']['title']
|
|
= _n('Computer type', 'Computer types', Session::getPluralNumber());
|
|
$menu['dictionnary']['options']['type.computer']['page']
|
|
= '/front/ruledictionnarycomputertype.php';
|
|
$menu['dictionnary']['options']['type.computer']['links']['search']
|
|
= '/front/ruledictionnarycomputertype.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['type.computer']['links']['add']
|
|
= '/front/ruledictionnarycomputertype.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['type.monitor']['title']
|
|
= _n('Monitor type', 'Monitors types', Session::getPluralNumber());
|
|
$menu['dictionnary']['options']['type.monitor']['page']
|
|
= '/front/ruledictionnarymonitortype.php';
|
|
$menu['dictionnary']['options']['type.monitor']['links']['search']
|
|
= '/front/ruledictionnarymonitortype.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['type.monitor']['links']['add']
|
|
= '/front/ruledictionnarymonitortype.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['type.printer']['title']
|
|
= _n('Printer type', 'Printer types', Session::getPluralNumber());
|
|
$menu['dictionnary']['options']['type.printer']['page']
|
|
= '/front/ruledictionnaryprintertype.php';
|
|
$menu['dictionnary']['options']['type.printer']['links']['search']
|
|
= '/front/ruledictionnaryprintertype.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['type.printer']['links']['add']
|
|
= '/front/ruledictionnaryprintertype.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['type.peripheral']['title']
|
|
= _n('Peripheral type', 'Peripheral types', Session::getPluralNumber());
|
|
$menu['dictionnary']['options']['type.peripheral']['page']
|
|
= '/front/ruledictionnaryperipheraltype.php';
|
|
$menu['dictionnary']['options']['type.peripheral']['links']['search']
|
|
= '/front/ruledictionnaryperipheraltype.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['type.peripheral']['links']['add']
|
|
= '/front/ruledictionnaryperipheraltype.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['type.networking']['title']
|
|
= _n('Networking equipment type', 'Networking equipment types', Session::getPluralNumber());
|
|
$menu['dictionnary']['options']['type.networking']['page']
|
|
= '/front/ruledictionnarynetworkequipmenttype.php';
|
|
$menu['dictionnary']['options']['type.networking']['links']['search']
|
|
= '/front/ruledictionnarynetworkequipmenttype.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['type.networking']['links']['add']
|
|
= '/front/ruledictionnarynetworkequipmenttype.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['type.phone']['title']
|
|
= _n('Phone type', 'Phone types', Session::getPluralNumber());
|
|
$menu['dictionnary']['options']['type.phone']['page']
|
|
= '/front/ruledictionnaryphonetype.php';
|
|
$menu['dictionnary']['options']['type.phone']['links']['search']
|
|
= '/front/ruledictionnaryphonetype.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['type.phone']['links']['add']
|
|
= '/front/ruledictionnaryphonetype.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['os']['title']
|
|
= OperatingSystem::getTypeName(1);
|
|
$menu['dictionnary']['options']['os']['page']
|
|
= '/front/ruledictionnaryoperatingsystem.php';
|
|
$menu['dictionnary']['options']['os']['links']['search']
|
|
= '/front/ruledictionnaryoperatingsystem.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['os']['links']['add']
|
|
= '/front/ruledictionnaryoperatingsystem.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['os_sp']['title']
|
|
= OperatingSystemServicePack::getTypeName(1);
|
|
$menu['dictionnary']['options']['os_sp']['page']
|
|
= '/front/ruledictionnaryoperatingsystemservicepack.php';
|
|
$menu['dictionnary']['options']['os_sp']['links']['search']
|
|
= '/front/ruledictionnaryoperatingsystemservicepack.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['os_sp']['links']['add']
|
|
= '/front/ruledictionnaryoperatingsystemservicepack.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['os_version']['title']
|
|
= OperatingSystemVersion::getTypeName(1);
|
|
$menu['dictionnary']['options']['os_version']['page']
|
|
= '/front/ruledictionnaryoperatingsystemversion.php';
|
|
$menu['dictionnary']['options']['os_version']['links']['search']
|
|
= '/front/ruledictionnaryoperatingsystemversion.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['os_version']['links']['add']
|
|
= '/front/ruledictionnaryoperatingsystemversion.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['os_arch']['title']
|
|
= OperatingSystemArchitecture::getTypeName(1);
|
|
$menu['dictionnary']['options']['os_arch']['page']
|
|
= '/front/ruledictionnaryoperatingsystemarchitecture.php';
|
|
$menu['dictionnary']['options']['os_arch']['links']['search']
|
|
= '/front/ruledictionnaryoperatingsystemarchitecture.php';
|
|
|
|
if (RuleDictionnaryDropdown::canCreate()) {
|
|
$menu['dictionnary']['options']['os_arch']['links']['add']
|
|
= '/front/ruledictionnaryoperatingsystemarchitecture.form.php';
|
|
}
|
|
|
|
$menu['dictionnary']['options']['printer']['title']
|
|
= _n('Printer', 'Printers', Session::getPluralNumber());
|
|
$menu['dictionnary']['options']['printer']['page']
|
|
= '/front/ruledictionnaryprinter.php';
|
|
$menu['dictionnary']['options']['printer']['links']['search']
|
|
= '/front/ruledictionnaryprinter.php';
|
|
|
|
if (RuleDictionnaryPrinter::canCreate()) {
|
|
$menu['dictionnary']['options']['printer']['links']['add']
|
|
= '/front/ruledictionnaryprinter.form.php';
|
|
}
|
|
}
|
|
|
|
if (count($menu)) {
|
|
$menu['is_multi_entries'] = true;
|
|
return $menu;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* @since versin 0.84
|
|
**/
|
|
function getRuleActionClass () {
|
|
return $this->ruleactionclass;
|
|
}
|
|
|
|
|
|
/**
|
|
* @since versin 0.84
|
|
**/
|
|
function getRuleCriteriaClass () {
|
|
return $this->rulecriteriaclass;
|
|
}
|
|
|
|
|
|
/**
|
|
* @since versin 0.84
|
|
**/
|
|
function getRuleIdField () {
|
|
return $this->rules_id_field;
|
|
}
|
|
|
|
|
|
function isEntityAssign() {
|
|
return false;
|
|
}
|
|
|
|
|
|
function post_getEmpty() {
|
|
$this->fields['is_active'] = 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get title used in rule
|
|
*
|
|
* @return Title of the rule
|
|
**/
|
|
function getTitle() {
|
|
return __('Rules management');
|
|
}
|
|
|
|
|
|
/**
|
|
* @since 0.84
|
|
*
|
|
* @return string
|
|
**/
|
|
function getCollectionClassName() {
|
|
return $this->getType().'Collection';
|
|
}
|
|
|
|
|
|
/**
|
|
* @see CommonDBTM::getSpecificMassiveActions()
|
|
**/
|
|
function getSpecificMassiveActions($checkitem = null) {
|
|
|
|
$isadmin = static::canUpdate();
|
|
$actions = parent::getSpecificMassiveActions($checkitem);
|
|
|
|
$collectiontype = $this->getCollectionClassName();
|
|
if ($collection = getItemForItemtype($collectiontype)) {
|
|
if ($isadmin
|
|
&& ($collection->orderby == "ranking")) {
|
|
$actions[__CLASS__.MassiveAction::CLASS_ACTION_SEPARATOR.'move_rule']
|
|
= "<i class='ma-icon fas fa-arrows-alt-v'></i>".
|
|
__('Move');
|
|
}
|
|
$actions[__CLASS__.MassiveAction::CLASS_ACTION_SEPARATOR.'export']
|
|
= "<i class='ma-icon fas fa-file-download'></i>".
|
|
_x('button', 'Export');
|
|
}
|
|
return $actions;
|
|
}
|
|
|
|
|
|
/**
|
|
* @since 0.85
|
|
*
|
|
* @see CommonDBTM::showMassiveActionsSubForm()
|
|
**/
|
|
static function showMassiveActionsSubForm(MassiveAction $ma) {
|
|
|
|
switch ($ma->getAction()) {
|
|
case 'move_rule' :
|
|
$input = $ma->getInput();
|
|
$values = ['after' => __('After'),
|
|
'before' => __('Before')];
|
|
Dropdown::showFromArray('move_type', $values, ['width' => '20%']);
|
|
|
|
if (isset($input['entity'])) {
|
|
$entity = $input['entity'];
|
|
} else {
|
|
$entity = "";
|
|
}
|
|
|
|
if (isset($input['condition'])) {
|
|
$condition = $input['condition'];
|
|
} else {
|
|
$condition = 0;
|
|
}
|
|
echo Html::hidden('rule_class_name', ['value' => $input['rule_class_name']]);
|
|
|
|
Rule::dropdown(['sub_type' => $input['rule_class_name'],
|
|
'name' => "ranking",
|
|
'condition' => $condition,
|
|
'entity' => $entity,
|
|
'width' => '50%']);
|
|
echo "<br><br><input type='submit' name='massiveaction' class='submit' value='".
|
|
_sx('button', 'Move')."'>\n";
|
|
return true;
|
|
}
|
|
return parent::showMassiveActionsSubForm($ma);
|
|
}
|
|
|
|
|
|
/**
|
|
* @since 0.85
|
|
*
|
|
* @see CommonDBTM::processMassiveActionsForOneItemtype()
|
|
**/
|
|
static function processMassiveActionsForOneItemtype(MassiveAction $ma, CommonDBTM $item,
|
|
array $ids) {
|
|
switch ($ma->getAction()) {
|
|
case 'export':
|
|
if (count($ids)) {
|
|
$_SESSION['exportitems'] = $ids;
|
|
$ma->itemDone($item->getType(), $ids, MassiveAction::ACTION_OK);
|
|
$ma->setRedirect('rule.backup.php?action=download&itemtype='.$item->getType());
|
|
}
|
|
break;
|
|
|
|
case 'move_rule' :
|
|
$input = $ma->getInput();
|
|
$collectionname = $input['rule_class_name'].'Collection';
|
|
$rulecollection = new $collectionname();
|
|
if ($rulecollection->canUpdate()) {
|
|
foreach ($ids as $id) {
|
|
if ($item->getFromDB($id)) {
|
|
if ($rulecollection->moveRule($id, $input['ranking'], $input['move_type'])) {
|
|
$ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK);
|
|
} else {
|
|
$ma->itemDone($item->getType(), $id, MassiveAction::ACTION_KO);
|
|
$ma->addMessage($item->getErrorMessage(ERROR_ON_ACTION));
|
|
}
|
|
} else {
|
|
$ma->itemDone($item->getType(), $id, MassiveAction::ACTION_KO);
|
|
$ma->addMessage($item->getErrorMessage(ERROR_NOT_FOUND));
|
|
}
|
|
}
|
|
} else {
|
|
$ma->itemDone($item->getType(), $ids, MassiveAction::ACTION_NORIGHT);
|
|
$ma->addMessage($item->getErrorMessage(ERROR_RIGHT));
|
|
}
|
|
break;
|
|
}
|
|
parent::processMassiveActionsForOneItemtype($ma, $item, $ids);
|
|
}
|
|
|
|
|
|
function rawSearchOptions() {
|
|
$tab = [];
|
|
|
|
$tab[] = [
|
|
'id' => '1',
|
|
'table' => $this->getTable(),
|
|
'field' => 'name',
|
|
'name' => __('Name'),
|
|
'datatype' => 'itemlink',
|
|
'massiveaction' => false,
|
|
'autocomplete' => true,
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '2',
|
|
'table' => $this->getTable(),
|
|
'field' => 'id',
|
|
'name' => __('ID'),
|
|
'massiveaction' => false,
|
|
'datatype' => 'number'
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '3',
|
|
'table' => $this->getTable(),
|
|
'field' => 'ranking',
|
|
'name' => __('Ranking'),
|
|
'datatype' => 'number',
|
|
'massiveaction' => false
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '4',
|
|
'table' => $this->getTable(),
|
|
'field' => 'description',
|
|
'name' => __('Description'),
|
|
'datatype' => 'text',
|
|
'autocomplete' => true,
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '5',
|
|
'table' => $this->getTable(),
|
|
'field' => 'match',
|
|
'name' => __('Logical operator'),
|
|
'datatype' => 'specific',
|
|
'massiveaction' => false
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '8',
|
|
'table' => $this->getTable(),
|
|
'field' => 'is_active',
|
|
'name' => __('Active'),
|
|
'datatype' => 'bool'
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '16',
|
|
'table' => $this->getTable(),
|
|
'field' => 'comment',
|
|
'name' => __('Comments'),
|
|
'datatype' => 'text'
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '80',
|
|
'table' => 'glpi_entities',
|
|
'field' => 'completename',
|
|
'name' => Entity::getTypeName(1),
|
|
'massiveaction' => false,
|
|
'datatype' => 'dropdown'
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '86',
|
|
'table' => $this->getTable(),
|
|
'field' => 'is_recursive',
|
|
'name' => __('Child entities'),
|
|
'datatype' => 'bool',
|
|
'massiveaction' => false
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '19',
|
|
'table' => $this->getTable(),
|
|
'field' => 'date_mod',
|
|
'name' => __('Last update'),
|
|
'datatype' => 'datetime',
|
|
'massiveaction' => false
|
|
];
|
|
|
|
$tab[] = [
|
|
'id' => '121',
|
|
'table' => $this->getTable(),
|
|
'field' => 'date_creation',
|
|
'name' => __('Creation date'),
|
|
'datatype' => 'datetime',
|
|
'massiveaction' => false
|
|
];
|
|
|
|
return $tab;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $field
|
|
* @param $values
|
|
* @param $options array
|
|
*
|
|
* @return string
|
|
**/
|
|
static function getSpecificValueToDisplay($field, $values, array $options = []) {
|
|
|
|
if (!is_array($values)) {
|
|
$values = [$field => $values];
|
|
}
|
|
switch ($field) {
|
|
case 'match' :
|
|
switch ($values[$field]) {
|
|
case self::AND_MATCHING :
|
|
return __('and');
|
|
|
|
case self::OR_MATCHING :
|
|
return __('or');
|
|
|
|
default :
|
|
return NOT_AVAILABLE;
|
|
}
|
|
break;
|
|
}
|
|
return parent::getSpecificValueToDisplay($field, $values, $options);
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $field
|
|
* @param $name (default '')
|
|
* @param $values (default '')
|
|
* @param $options array
|
|
**/
|
|
static function getSpecificValueToSelect($field, $name = '', $values = '', array $options = []) {
|
|
|
|
if (!is_array($values)) {
|
|
$values = [$field => $values];
|
|
}
|
|
$options['display'] = false;
|
|
switch ($field) {
|
|
case 'match' :
|
|
if (isset($values['itemtype']) && !empty($values['itemtype'])) {
|
|
$options['value'] = $values[$field];
|
|
$options['name'] = $name;
|
|
$rule = new static();
|
|
return $rule->dropdownRulesMatch($options);
|
|
}
|
|
break;
|
|
}
|
|
return parent::getSpecificValueToSelect($field, $name, $values, $options);
|
|
}
|
|
|
|
|
|
/**
|
|
* Show the rule
|
|
*
|
|
* @param $ID ID of the rule
|
|
* @param $options array of possible options:
|
|
* - target filename : where to go when done.
|
|
* - withtemplate boolean : template or basic item
|
|
*
|
|
* @return void
|
|
**/
|
|
function showForm($ID, $options = []) {
|
|
global $CFG_GLPI;
|
|
if (!$this->isNewID($ID)) {
|
|
$this->check($ID, READ);
|
|
} else {
|
|
// Create item
|
|
$this->checkGlobal(UPDATE);
|
|
}
|
|
|
|
$canedit = $this->canEdit(static::$rightname);
|
|
$rand = mt_rand();
|
|
$this->showFormHeader($options);
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>".__('Name')."</td>";
|
|
echo "<td>";
|
|
Html::autocompletionTextField($this, "name");
|
|
echo "</td>";
|
|
echo "<td>".__('Description')."</td>";
|
|
echo "<td>";
|
|
Html::autocompletionTextField($this, "description");
|
|
echo "</td></tr>\n";
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>".__('Logical operator')."</td>";
|
|
echo "<td>";
|
|
$this->dropdownRulesMatch(['value' => $this->fields["match"]]);
|
|
echo "</td>";
|
|
echo "<td>".__('Active')."</td>";
|
|
echo "<td>";
|
|
Dropdown::showYesNo("is_active", $this->fields["is_active"]);
|
|
echo "</td></tr>\n";
|
|
|
|
if ($this->useConditions()) {
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>".__('Use rule for')."</td>";
|
|
echo "<td>";
|
|
$this->dropdownConditions(['value' => $this->fields["condition"]]);
|
|
echo "</td>";
|
|
echo "<td colspan='2'>";
|
|
echo "</td></tr>\n";
|
|
}
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>".__('Comments')."</td>";
|
|
echo "<td class='middle' colspan='3'>";
|
|
echo "<textarea cols='110' rows='3' name='comment' >".$this->fields["comment"]."</textarea>";
|
|
|
|
if (!$this->isNewID($ID)) {
|
|
if ($this->fields["date_mod"]) {
|
|
echo "<br>";
|
|
printf(__('Last update on %s'), Html::convDateTime($this->fields["date_mod"]));
|
|
}
|
|
}
|
|
if ($canedit) {
|
|
if (!$this->isNewID($ID)) {
|
|
echo "<input type='hidden' name='ranking' value='".$this->fields["ranking"]."'>";
|
|
}
|
|
echo "<input type='hidden' name='sub_type' value='".get_class($this)."'>";
|
|
}
|
|
echo "</td></tr>\n";
|
|
|
|
if ($canedit) {
|
|
if ($ID > 0) {
|
|
if ($plugin = isPluginItemType($this->getType())) {
|
|
$url = $CFG_GLPI["root_doc"]."/plugins/".strtolower($plugin['plugin']);
|
|
} else {
|
|
$url = $CFG_GLPI["root_doc"];
|
|
}
|
|
echo "<tr><td class='tab_bg_2 center' colspan='4'>";
|
|
echo "<a class='vsubmit' href='#' onClick=\"".
|
|
Html::jsGetElementbyID('ruletest'.$rand).".dialog('open'); return false;\">".
|
|
_x('button', 'Test')."</a>";
|
|
Ajax::createIframeModalWindow('ruletest'.$rand,
|
|
$url."/front/rule.test.php?". "sub_type=".$this->getType().
|
|
"&rules_id=".$this->fields["id"],
|
|
['title' => _x('button', 'Test')]);
|
|
echo "</td></tr>\n";
|
|
}
|
|
}
|
|
|
|
$this->showFormButtons($options);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* Display a dropdown with all the rule matching
|
|
*
|
|
* @since 0.84 new proto
|
|
*
|
|
* @param $options array of parameters
|
|
**/
|
|
function dropdownRulesMatch($options = []) {
|
|
|
|
$p['name'] = 'match';
|
|
$p['value'] = '';
|
|
$p['restrict'] = $this->restrict_matching;
|
|
$p['display'] = true;
|
|
|
|
if (is_array($options) && count($options)) {
|
|
foreach ($options as $key => $val) {
|
|
$p[$key] = $val;
|
|
}
|
|
}
|
|
|
|
if (!$p['restrict'] || ($p['restrict'] == self::AND_MATCHING)) {
|
|
$elements[self::AND_MATCHING] = __('and');
|
|
}
|
|
|
|
if (!$p['restrict'] || ($p['restrict'] == self::OR_MATCHING)) {
|
|
$elements[self::OR_MATCHING] = __('or');
|
|
}
|
|
|
|
return Dropdown::showFromArray($p['name'], $elements, $p);
|
|
}
|
|
|
|
|
|
/**
|
|
* Get all criterias for a given rule
|
|
*
|
|
* @param $ID the rule_description ID
|
|
* @param $withcriterias 1 to retrieve all the criterias for a given rule (default 0)
|
|
* @param $withactions 1 to retrive all the actions for a given rule (default 0)
|
|
**/
|
|
function getRuleWithCriteriasAndActions($ID, $withcriterias = 0, $withactions = 0) {
|
|
|
|
if ($ID == "") {
|
|
return $this->getEmpty();
|
|
}
|
|
if ($ret = $this->getFromDB($ID)) {
|
|
if ($withactions
|
|
&& ($RuleAction = getItemForItemtype($this->ruleactionclass))) {
|
|
$this->actions = $RuleAction->getRuleActions($ID);
|
|
}
|
|
|
|
if ($withcriterias
|
|
&& ($RuleCriterias = getItemForItemtype($this->rulecriteriaclass))) {
|
|
$this->criterias = $RuleCriterias->getRuleCriterias($ID);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* display title for action form
|
|
**/
|
|
function getTitleAction() {
|
|
|
|
foreach ($this->getActions() as $key => $val) {
|
|
if (isset($val['force_actions'])
|
|
&& (in_array('regex_result', $val['force_actions'])
|
|
|| in_array('append_regex_result', $val['force_actions']))) {
|
|
|
|
echo "<table class='tab_cadre_fixe'>";
|
|
echo "<tr class='tab_bg_2'><td>".
|
|
__('It is possible to affect the result of a regular expression using the string #0').
|
|
"</td></tr>\n";
|
|
echo "</table><br>";
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Get maximum number of Actions of the Rule (0 = unlimited)
|
|
*
|
|
* @return the maximum number of actions
|
|
**/
|
|
function maxActionsCount() {
|
|
return count(array_filter($this->getAllActions(), function($action_obj) {
|
|
return !isset($action_obj['duplicatewith']);
|
|
}));
|
|
}
|
|
|
|
|
|
/**
|
|
* Display all rules actions
|
|
*
|
|
* @param $rules_id rule ID
|
|
* @param $options array of options : may be readonly
|
|
**/
|
|
function showActionsList($rules_id, $options = []) {
|
|
global $CFG_GLPI;
|
|
|
|
$rand = mt_rand();
|
|
$p['readonly'] = false;
|
|
|
|
if (is_array($options) && count($options)) {
|
|
foreach ($options as $key => $val) {
|
|
$p[$key] = $val;
|
|
}
|
|
}
|
|
|
|
$canedit = $this->canEdit($rules_id);
|
|
$style = "class='tab_cadre_fixehov'";
|
|
|
|
if ($p['readonly']) {
|
|
$canedit = false;
|
|
$style = "class='tab_cadrehov'";
|
|
}
|
|
$this->getTitleAction();
|
|
|
|
if ($canedit) {
|
|
echo "<div id='viewaction" . $rules_id . "$rand'></div>\n";
|
|
}
|
|
|
|
if ($canedit
|
|
&& (($this->maxActionsCount() == 0)
|
|
|| (sizeof($this->actions) < $this->maxActionsCount()))) {
|
|
|
|
echo "<script type='text/javascript' >\n";
|
|
echo "function viewAddAction" . $rules_id . "$rand() {\n";
|
|
$params = ['type' => $this->ruleactionclass,
|
|
'parenttype' => $this->getType(),
|
|
$this->rules_id_field => $rules_id,
|
|
'id' => -1];
|
|
Ajax::updateItemJsCode("viewaction" . $rules_id . "$rand",
|
|
$CFG_GLPI["root_doc"]."/ajax/viewsubitem.php", $params);
|
|
echo "};";
|
|
echo "</script>\n";
|
|
echo "<div class='center firstbloc'>".
|
|
"<a class='vsubmit' href='javascript:viewAddAction".$rules_id."$rand();'>";
|
|
echo __('Add a new action')."</a></div>\n";
|
|
}
|
|
|
|
$nb = count($this->actions);
|
|
|
|
echo "<div class='spaced'>";
|
|
if ($canedit && $nb) {
|
|
Html::openMassiveActionsForm('mass'.$this->ruleactionclass.$rand);
|
|
$massiveactionparams = ['num_displayed' => min($_SESSION['glpilist_limit'], $nb),
|
|
'check_itemtype' => get_class($this),
|
|
'check_items_id' => $rules_id,
|
|
'container' => 'mass'.$this->ruleactionclass.$rand,
|
|
'extraparams' => ['rule_class_name'
|
|
=> $this->getType()]];
|
|
Html::showMassiveActions($massiveactionparams);
|
|
}
|
|
|
|
echo "<table $style>";
|
|
echo "<tr class='noHover'>";
|
|
echo "<th colspan='".($canedit && $nb?'4':'3')."'>" . _n('Action', 'Actions', Session::getPluralNumber()) . "</th></tr>";
|
|
|
|
$header_begin = "<tr>";
|
|
$header_top = '';
|
|
$header_bottom = '';
|
|
$header_end = '';
|
|
|
|
if ($canedit && $nb) {
|
|
$header_top .= "<th width='10'>";
|
|
$header_top .= Html::getCheckAllAsCheckbox('mass'.$this->ruleactionclass.$rand)."</th>";
|
|
$header_bottom .= "<th width='10'>";
|
|
$header_bottom .= Html::getCheckAllAsCheckbox('mass'.$this->ruleactionclass.$rand)."</th>";
|
|
}
|
|
|
|
$header_end .= "<th class='center b'>"._n('Field', 'Fields', Session::getPluralNumber())."</th>";
|
|
$header_end .= "<th class='center b'>".__('Action type')."</th>";
|
|
$header_end .= "<th class='center b'>".__('Value')."</th>";
|
|
$header_end .= "</tr>\n";
|
|
echo $header_begin.$header_top.$header_end;
|
|
|
|
foreach ($this->actions as $action) {
|
|
$this->showMinimalActionForm($action->fields, $canedit, $rand);
|
|
}
|
|
if ($nb) {
|
|
echo $header_begin.$header_bottom.$header_end;
|
|
}
|
|
echo "</table>\n";
|
|
|
|
if ($canedit && $nb) {
|
|
$massiveactionparams['ontop'] = false;
|
|
Html::showMassiveActions($massiveactionparams);
|
|
Html::closeForm();
|
|
}
|
|
echo "</div>";
|
|
}
|
|
|
|
|
|
function maybeRecursive() {
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Display all rules criterias
|
|
*
|
|
* @param $rules_id
|
|
* @param $options array of options : may be readonly
|
|
**/
|
|
function showCriteriasList($rules_id, $options = []) {
|
|
global $CFG_GLPI;
|
|
|
|
$rand = mt_rand();
|
|
$p['readonly'] = false;
|
|
|
|
if (is_array($options) && count($options)) {
|
|
foreach ($options as $key => $val) {
|
|
$p[$key] = $val;
|
|
}
|
|
}
|
|
|
|
$canedit = $this->canEdit($rules_id);
|
|
$style = "class='tab_cadre_fixehov'";
|
|
|
|
if ($p['readonly']) {
|
|
$canedit = false;
|
|
$style = "class='tab_cadrehov'";
|
|
}
|
|
|
|
if ($canedit) {
|
|
echo "<div id='viewcriteria" . $rules_id . "$rand'></div>\n";
|
|
|
|
echo "<script type='text/javascript' >\n";
|
|
echo "function viewAddCriteria" . $rules_id . "$rand() {\n";
|
|
$params = ['type' => $this->rulecriteriaclass,
|
|
'parenttype' => $this->getType(),
|
|
$this->rules_id_field => $rules_id,
|
|
'id' => -1];
|
|
Ajax::updateItemJsCode("viewcriteria" . $rules_id . "$rand",
|
|
$CFG_GLPI["root_doc"]."/ajax/viewsubitem.php", $params);
|
|
echo "};";
|
|
echo "</script>\n";
|
|
echo "<div class='center firstbloc'>".
|
|
"<a class='vsubmit' href='javascript:viewAddCriteria".$rules_id."$rand();'>";
|
|
echo __('Add a new criterion')."</a></div>\n";
|
|
}
|
|
|
|
echo "<div class='spaced'>";
|
|
|
|
$nb = sizeof($this->criterias);
|
|
|
|
if ($canedit && $nb) {
|
|
Html::openMassiveActionsForm('mass'.$this->rulecriteriaclass.$rand);
|
|
$massiveactionparams = ['num_displayed' => min($_SESSION['glpilist_limit'], $nb),
|
|
'check_itemtype' => get_class($this),
|
|
'check_items_id' => $rules_id,
|
|
'container' => 'mass'.$this->rulecriteriaclass.$rand,
|
|
'extraparams' => ['rule_class_name'
|
|
=> $this->getType()]];
|
|
Html::showMassiveActions($massiveactionparams);
|
|
}
|
|
|
|
echo "<table $style>";
|
|
echo "<tr class='noHover'>".
|
|
"<th colspan='".($canedit&&$nb?" 4 ":"3")."'>". _n('Criterion', 'Criteria', Session::getPluralNumber())."</th>".
|
|
"</tr>\n";
|
|
|
|
$header_begin = "<tr>";
|
|
$header_top = '';
|
|
$header_bottom = '';
|
|
$header_end = '';
|
|
|
|
if ($canedit && $nb) {
|
|
$header_top .= "<th width='10'>";
|
|
$header_top .= Html::getCheckAllAsCheckbox('mass'.$this->rulecriteriaclass.$rand);
|
|
$header_top .= "</th>";
|
|
$header_bottom .= "<th width='10'>";
|
|
$header_bottom .= Html::getCheckAllAsCheckbox('mass'.$this->rulecriteriaclass.$rand);
|
|
$header_bottom .= "</th>";
|
|
}
|
|
$header_end .= "<th class='center b'>"._n('Criterion', 'Criteria', 1)."</th>\n";
|
|
$header_end .= "<th class='center b'>".__('Condition')."</th>\n";
|
|
$header_end .= "<th class='center b'>".__('Reason')."</th>\n";
|
|
$header_end .= "</tr>\n";
|
|
echo $header_begin.$header_top.$header_end;
|
|
|
|
foreach ($this->criterias as $criterion) {
|
|
$this->showMinimalCriteriaForm($criterion->fields, $canedit, $rand);
|
|
}
|
|
|
|
if ($nb) {
|
|
echo $header_begin.$header_bottom.$header_end;
|
|
}
|
|
echo "</table>\n";
|
|
|
|
if ($canedit && $nb) {
|
|
$massiveactionparams['ontop'] = false;
|
|
Html::showMassiveActions($massiveactionparams);
|
|
Html::closeForm();
|
|
}
|
|
|
|
echo "</div>\n";
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Display the dropdown of the criteria for the rule
|
|
*
|
|
* @since 0.84 new proto
|
|
*
|
|
* @param $options array of options : may be readonly
|
|
*
|
|
* @return the initial value (first)
|
|
**/
|
|
function dropdownCriteria($options = []) {
|
|
$p['name'] = 'criteria';
|
|
$p['display'] = true;
|
|
$p['value'] = '';
|
|
$p['display_emptychoice'] = true;
|
|
|
|
if (is_array($options) && count($options)) {
|
|
foreach ($options as $key => $val) {
|
|
$p[$key] = $val;
|
|
}
|
|
}
|
|
|
|
$group = [];
|
|
$groupname = _n('Criterion', 'Criteria', Session::getPluralNumber());
|
|
foreach ($this->getAllCriteria() as $ID => $crit) {
|
|
// Manage group system
|
|
if (!is_array($crit)) {
|
|
if (count($group)) {
|
|
asort($group);
|
|
$items[$groupname] = $group;
|
|
}
|
|
$group = [];
|
|
$groupname = $crit;
|
|
} else {
|
|
$group[$ID] = $crit['name'];
|
|
}
|
|
}
|
|
if (count($group)) {
|
|
asort($group);
|
|
$items[$groupname] = $group;
|
|
}
|
|
return Dropdown::showFromArray($p['name'], $items, $p);
|
|
}
|
|
|
|
|
|
/**
|
|
* Display the dropdown of the actions for the rule
|
|
*
|
|
* @param $options already used actions
|
|
*
|
|
* @return the initial value (first non used)
|
|
**/
|
|
function dropdownActions($options = []) {
|
|
$p['name'] = 'field';
|
|
$p['display'] = true;
|
|
$p['used'] = [];
|
|
$p['value'] = '';
|
|
$p['display_emptychoice'] = true;
|
|
|
|
if (is_array($options) && count($options)) {
|
|
foreach ($options as $key => $val) {
|
|
$p[$key] = $val;
|
|
}
|
|
}
|
|
|
|
$actions = $this->getAllActions();
|
|
|
|
// For each used actions see if several set is available
|
|
// Force actions to available actions for several
|
|
foreach ($p['used'] as $key => $ID) {
|
|
if (isset($actions[$ID]['permitseveral'])) {
|
|
unset($p['used'][$key]);
|
|
}
|
|
}
|
|
|
|
// Complete used array with duplicate items
|
|
// add duplicates of used items
|
|
foreach ($p['used'] as $ID) {
|
|
if (isset($actions[$ID]['duplicatewith'])) {
|
|
$p['used'][$actions[$ID]['duplicatewith']] = $actions[$ID]['duplicatewith'];
|
|
}
|
|
}
|
|
|
|
// Parse for duplicates of already used items
|
|
foreach ($actions as $ID => $act) {
|
|
if (isset($actions[$ID]['duplicatewith'])
|
|
&& in_array($actions[$ID]['duplicatewith'], $p['used'])) {
|
|
$p['used'][$ID] = $ID;
|
|
}
|
|
}
|
|
|
|
$value = '';
|
|
|
|
foreach ($actions as $ID => $act) {
|
|
$items[$ID] = $act['name'];
|
|
|
|
if (empty($value) && !isset($used[$ID])) {
|
|
$value = $ID;
|
|
}
|
|
}
|
|
return Dropdown::showFromArray($p['name'], $items, $p);
|
|
}
|
|
|
|
|
|
/**
|
|
* Get a criteria description by his ID
|
|
*
|
|
* @param $ID the criteria's ID
|
|
*
|
|
* @return the criteria array
|
|
**/
|
|
function getCriteria($ID) {
|
|
|
|
$criteria = $this->getAllCriteria();
|
|
if (isset($criteria[$ID])) {
|
|
return $criteria[$ID];
|
|
}
|
|
return [];
|
|
}
|
|
|
|
|
|
/**
|
|
* Get a action description by his ID
|
|
*
|
|
* @param $ID the action's ID
|
|
*
|
|
* @return the action array
|
|
**/
|
|
function getAction($ID) {
|
|
|
|
$actions = $this->getAllActions();
|
|
if (isset($actions[$ID])) {
|
|
return $actions[$ID];
|
|
}
|
|
return [];
|
|
}
|
|
|
|
|
|
/**
|
|
* Get a criteria description by his ID
|
|
*
|
|
* @param $ID the criteria's ID
|
|
*
|
|
* @return the criteria's description
|
|
**/
|
|
|
|
function getCriteriaName($ID) {
|
|
|
|
$criteria = $this->getCriteria($ID);
|
|
if (isset($criteria['name'])) {
|
|
return $criteria['name'];
|
|
}
|
|
return __('Unavailable')." ";
|
|
}
|
|
|
|
|
|
/**
|
|
* Get a action description by his ID
|
|
*
|
|
* @param $ID the action's ID
|
|
*
|
|
* @return the action's description
|
|
**/
|
|
function getActionName($ID) {
|
|
|
|
$action = $this->getAction($ID);
|
|
if (isset($action['name'])) {
|
|
return $action['name'];
|
|
}
|
|
return " ";
|
|
}
|
|
|
|
|
|
/**
|
|
* Process the rule
|
|
*
|
|
* @param &$input the input data used to check criteria
|
|
* @param &$output the initial output array used to be manipulate by actions
|
|
* @param &$params parameters for all internal functions
|
|
* @param &options array options:
|
|
* - only_criteria : only react on specific criteria
|
|
*
|
|
* @return the output array updated by actions.
|
|
* If rule matched add field _rule_process to return value
|
|
**/
|
|
function process(&$input, &$output, &$params, &$options = []) {
|
|
|
|
if ($this->validateCriterias($options)) {
|
|
$this->regex_results = [];
|
|
$this->criterias_results = [];
|
|
$input = $this->prepareInputDataForProcess($input, $params);
|
|
|
|
if ($this->checkCriterias($input)) {
|
|
unset($output["_no_rule_matches"]);
|
|
$refoutput = $output;
|
|
$output = $this->executeActions($output, $params, $input);
|
|
|
|
$this->updateOnlyCriteria($options, $refoutput, $output);
|
|
//Hook
|
|
$hook_params["sub_type"] = $this->getType();
|
|
$hook_params["ruleid"] = $this->fields["id"];
|
|
$hook_params["input"] = $input;
|
|
$hook_params["output"] = $output;
|
|
Plugin::doHook("rule_matched", $hook_params);
|
|
$output["_rule_process"] = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Update Only criteria options if needed
|
|
*
|
|
* @param &options options :
|
|
* - only_criteria : only react on specific criteria
|
|
* @param $refoutput the initial output array used to be manipulate by actions
|
|
* @param $newoutput the output array after actions process
|
|
*
|
|
* @return the options array updated.
|
|
**/
|
|
function updateOnlyCriteria(&$options, $refoutput, $newoutput) {
|
|
|
|
if (count($this->actions)) {
|
|
if (isset($options['only_criteria'])
|
|
&& !is_null($options['only_criteria'])
|
|
&& is_array($options['only_criteria'])) {
|
|
foreach ($this->actions as $action) {
|
|
if (!isset($refoutput[$action->fields["field"]])
|
|
|| ($refoutput[$action->fields["field"]]
|
|
!= $newoutput[$action->fields["field"]])) {
|
|
if (!in_array($action->fields["field"], $options['only_criteria'])) {
|
|
$options['only_criteria'][] = $action->fields["field"];
|
|
}
|
|
|
|
// Add linked criteria if available
|
|
$crit = $this->getCriteria($action->fields["field"]);
|
|
if (isset($crit['linked_criteria'])) {
|
|
$tmp = $crit['linked_criteria'];
|
|
if (!is_array($crit['linked_criteria'])) {
|
|
$tmp = [$tmp];
|
|
}
|
|
foreach ($tmp as $toadd) {
|
|
if (!in_array($toadd, $options['only_criteria'])) {
|
|
$options['only_criteria'][] = $toadd;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Are criteria valid to be processed
|
|
*
|
|
* @since 0.85
|
|
*
|
|
* @param array $options
|
|
*
|
|
* @return boolean
|
|
**/
|
|
function validateCriterias($options) {
|
|
|
|
if (count($this->criterias)) {
|
|
if (isset($options['only_criteria'])
|
|
&& !is_null($options['only_criteria'])
|
|
&& is_array($options['only_criteria'])) {
|
|
foreach ($this->criterias as $criterion) {
|
|
if (in_array($criterion->fields['criteria'], $options['only_criteria'])) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Check criteria
|
|
*
|
|
* @param aray $input the input data used to check criteri
|
|
*
|
|
* @return boolean if criteria match
|
|
**/
|
|
function checkCriterias($input) {
|
|
|
|
reset($this->criterias);
|
|
|
|
if ($this->fields["match"] == self::AND_MATCHING) {
|
|
$doactions = true;
|
|
|
|
foreach ($this->criterias as $criterion) {
|
|
|
|
$definition_criterion = $this->getCriteria($criterion->fields['criteria']);
|
|
if (!isset($definition_criterion['is_global']) || !$definition_criterion['is_global']) {
|
|
$doactions &= $this->checkCriteria($criterion, $input);
|
|
if (!$doactions) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
} else { // OR MATCHING
|
|
$doactions = false;
|
|
foreach ($this->criterias as $criterion) {
|
|
$definition_criterion = $this->getCriteria($criterion->fields['criteria']);
|
|
|
|
if (!isset($definition_criterion['is_global'])
|
|
|| !$definition_criterion['is_global']) {
|
|
$doactions |= $this->checkCriteria($criterion, $input);
|
|
if ($doactions) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//If all simple criteria match, and if necessary, check complex criteria
|
|
if ($doactions) {
|
|
return $this->findWithGlobalCriteria($input);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Check criteria
|
|
*
|
|
* @param array $input the input data used to check criteria
|
|
* @param array &$check_results
|
|
*
|
|
* @return boolean if criteria match
|
|
**/
|
|
function testCriterias($input, &$check_results) {
|
|
|
|
reset($this->criterias);
|
|
|
|
foreach ($this->criterias as $criterion) {
|
|
$result = $this->checkCriteria($criterion, $input);
|
|
$check_results[$criterion->fields["id"]]["name"] = $criterion->fields["criteria"];
|
|
$check_results[$criterion->fields["id"]]["value"] = $criterion->fields["pattern"];
|
|
$check_results[$criterion->fields["id"]]["result"] = ((!$result)?0:1);
|
|
$check_results[$criterion->fields["id"]]["id"] = $criterion->fields["id"];
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Process a criteria of a rule
|
|
*
|
|
* @param &$criteria criteria to check
|
|
* @param &$input the input data used to check criteria
|
|
**/
|
|
function checkCriteria(&$criteria, &$input) {
|
|
|
|
$partial_regex_result = [];
|
|
// Undefine criteria field : set to blank
|
|
if (!isset($input[$criteria->fields["criteria"]])) {
|
|
$input[$criteria->fields["criteria"]] = '';
|
|
}
|
|
|
|
//If the value is not an array
|
|
if (!is_array($input[$criteria->fields["criteria"]])) {
|
|
$value = $this->getCriteriaValue($criteria->fields["criteria"],
|
|
$criteria->fields["condition"],
|
|
$input[$criteria->fields["criteria"]]);
|
|
|
|
$res = RuleCriteria::match($criteria, $value, $this->criterias_results,
|
|
$partial_regex_result);
|
|
} else {
|
|
|
|
//If the value is, in fact, an array of values
|
|
// Negative condition : Need to match all condition (never be)
|
|
if (in_array($criteria->fields["condition"], [self::PATTERN_IS_NOT,
|
|
self::PATTERN_NOT_CONTAIN,
|
|
self::REGEX_NOT_MATCH,
|
|
self::PATTERN_DOES_NOT_EXISTS])) {
|
|
$res = true;
|
|
foreach ($input[$criteria->fields["criteria"]] as $tmp) {
|
|
$value = $this->getCriteriaValue($criteria->fields["criteria"],
|
|
$criteria->fields["condition"], $tmp);
|
|
|
|
$res &= RuleCriteria::match($criteria, $value, $this->criterias_results,
|
|
$partial_regex_result);
|
|
if (!$res) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
// Positive condition : Need to match one
|
|
$res = false;
|
|
foreach ($input[$criteria->fields["criteria"]] as $crit) {
|
|
$value = $this->getCriteriaValue($criteria->fields["criteria"],
|
|
$criteria->fields["condition"], $crit);
|
|
|
|
$res |= RuleCriteria::match($criteria, $value, $this->criterias_results,
|
|
$partial_regex_result);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Found regex on this criteria
|
|
if (count($partial_regex_result)) {
|
|
// No regex existing : put found
|
|
if (!count($this->regex_results)) {
|
|
$this->regex_results = $partial_regex_result;
|
|
|
|
} else { // Already existing regex : append found values
|
|
$temp_result = [];
|
|
foreach ($partial_regex_result as $new) {
|
|
|
|
foreach ($this->regex_results as $old) {
|
|
$temp_result[] = array_merge($old, $new);
|
|
}
|
|
}
|
|
$this->regex_results = $temp_result;
|
|
}
|
|
}
|
|
|
|
return $res;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $input
|
|
**/
|
|
function findWithGlobalCriteria($input) {
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* Specific prepare input datas for the rule
|
|
*
|
|
* @param $input the input data used to check criteria
|
|
* @param $params parameters
|
|
*
|
|
* @return the updated input datas
|
|
**/
|
|
function prepareInputDataForProcess($input, $params) {
|
|
return $input;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get all data needed to process rules (core + plugins)
|
|
*
|
|
* @since 0.84
|
|
* @param $input the input data used to check criteria
|
|
* @param $params parameters
|
|
*
|
|
* @return the updated input datas
|
|
**/
|
|
function prepareAllInputDataForProcess($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->getType(), $val)) {
|
|
$results = Plugin::doOneHook($plugin, "rulePrepareInputDataForProcess",
|
|
['input' => $input,
|
|
'params' => $params]);
|
|
if (is_array($results)) {
|
|
foreach ($results as $result) {
|
|
$input[] = $result;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $input;
|
|
}
|
|
|
|
|
|
/**
|
|
* Execute plugins actions if needed.
|
|
*
|
|
* @since 9.3.2 Added $input parameter
|
|
* @since 0.84
|
|
*
|
|
* @param RuleAction $action
|
|
* @param array $output rule execution output
|
|
* @param array $params parameters
|
|
* @param array $input the input data
|
|
*
|
|
* @return array Updated output
|
|
*/
|
|
function executePluginsActions($action, $output, $params, array $input = []) {
|
|
global $PLUGIN_HOOKS;
|
|
|
|
if (isset($PLUGIN_HOOKS['use_rules'])) {
|
|
$params['criterias_results'] = $this->criterias_results;
|
|
$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, "executeActions", ['output' => $output,
|
|
'params' => $params,
|
|
'action' => $action,
|
|
'input' => $input]);
|
|
if (is_array($results)) {
|
|
foreach ($results as $id => $result) {
|
|
$output[$id] = $result;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
return $output;
|
|
}
|
|
|
|
|
|
/**
|
|
* Execute the actions as defined in the rule.
|
|
*
|
|
* @since 9.3.2 Added $input parameter
|
|
*
|
|
* @param array $output the fields to manipulate
|
|
* @param array $params parameters
|
|
* @param array $input the input data
|
|
*
|
|
* @return array Updated output
|
|
**/
|
|
function executeActions($output, $params, array $input = []) {
|
|
|
|
if (count($this->actions)) {
|
|
foreach ($this->actions as $action) {
|
|
switch ($action->fields["action_type"]) {
|
|
case "assign" :
|
|
$output[$action->fields["field"]] = $action->fields["value"];
|
|
break;
|
|
|
|
case "append" :
|
|
$actions = $this->getActions();
|
|
$value = $action->fields["value"];
|
|
if (isset($actions[$action->fields["field"]]["appendtoarray"])
|
|
&& isset($actions[$action->fields["field"]]["appendtoarrayfield"])) {
|
|
$value = $actions[$action->fields["field"]]["appendtoarray"];
|
|
$value[$actions[$action->fields["field"]]["appendtoarrayfield"]]
|
|
= $action->fields["value"];
|
|
}
|
|
$output[$actions[$action->fields["field"]]["appendto"]][] = $value;
|
|
break;
|
|
|
|
case "regex_result" :
|
|
case "append_regex_result" :
|
|
//Regex result : assign value from the regex
|
|
//Append regex result : append result from a regex
|
|
if (isset($this->regex_results[0])) {
|
|
$res = RuleAction::getRegexResultById($action->fields["value"],
|
|
$this->regex_results[0]);
|
|
} else {
|
|
$res = $action->fields["value"];
|
|
}
|
|
|
|
if ($action->fields["action_type"] == "append_regex_result") {
|
|
if (isset($params[$action->fields["field"]])) {
|
|
$res = $params[$action->fields["field"]] . $res;
|
|
} else {
|
|
//keep rule value to append in a separate entry
|
|
$output[$action->fields['field'] . '_append'] = $res;
|
|
}
|
|
}
|
|
|
|
$output[$action->fields["field"]] = $res;
|
|
break;
|
|
|
|
default:
|
|
//plugins actions
|
|
$executeaction = clone $this;
|
|
$output = $executeaction->executePluginsActions($action, $output, $params, $input);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return $output;
|
|
}
|
|
|
|
|
|
function cleanDBonPurge() {
|
|
|
|
// Delete a rule and all associated criteria and actions
|
|
if (!empty($this->ruleactionclass)) {
|
|
$ruleactionclass = $this->ruleactionclass;
|
|
$ra = new $ruleactionclass();
|
|
$ra->deleteByCriteria([$this->rules_id_field => $this->fields['id']]);
|
|
}
|
|
|
|
if (!empty($this->rulecriteriaclass)) {
|
|
$rulecriteriaclass = $this->rulecriteriaclass;
|
|
$rc = new $rulecriteriaclass();
|
|
$rc->deleteByCriteria([$this->rules_id_field => $this->fields['id']]);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Show the minimal form for the rule
|
|
*
|
|
* @param $target link to the form page
|
|
* @param $first is it the first rule ?(false by default)
|
|
* @param $last is it the last rule ? (false by default)
|
|
* @param $display_entities display entities / make it read only display (false by default)
|
|
* @param $active_condition active condition used (default 0)
|
|
**/
|
|
function showMinimalForm($target, $first = false, $last = false, $display_entities = false, $active_condition = 0) {
|
|
global $CFG_GLPI;
|
|
|
|
$canedit = (self::canUpdate() && !$display_entities);
|
|
echo "<tr class='tab_bg_1'>";
|
|
|
|
if ($canedit) {
|
|
echo "<td width='10'>";
|
|
Html::showMassiveActionCheckBox($this->getType(), $this->fields["id"]);
|
|
echo "</td>";
|
|
|
|
} else {
|
|
echo "<td> </td>";
|
|
}
|
|
|
|
$link = $this->getLink();
|
|
if (!empty($this->fields["comment"])) {
|
|
$link = sprintf(__('%1$s %2$s'), $link,
|
|
Html::showToolTip($this->fields["comment"], ['display' => false]));
|
|
}
|
|
echo "<td>".$link."</td>";
|
|
echo "<td>".$this->fields["description"]."</td>";
|
|
if ($this->useConditions()) {
|
|
echo "<td>".$this->getConditionName($this->fields["condition"])."</td>";
|
|
}
|
|
echo "<td>".Dropdown::getYesNo($this->fields["is_active"])."</td>";
|
|
|
|
if ($display_entities) {
|
|
$entname = Dropdown::getDropdownName('glpi_entities', $this->fields['entities_id']);
|
|
if ($this->maybeRecursive()
|
|
&& $this->fields['is_recursive']) {
|
|
$entname = sprintf(__('%1$s %2$s'), $entname, "<span class='b'>(".__('R').")</span>");
|
|
}
|
|
|
|
echo "<td>".$entname."</td>";
|
|
}
|
|
|
|
if (!$display_entities) {
|
|
if ($this->can_sort
|
|
&& !$first
|
|
&& $canedit) {
|
|
echo "<td>";
|
|
Html::showSimpleForm($target, ['action' => 'up',
|
|
'condition' => $active_condition], '',
|
|
['type' => $this->fields["sub_type"],
|
|
'id' => $this->fields["id"],],
|
|
$CFG_GLPI["root_doc"]."/pics/deplier_up.png");
|
|
echo "</td>";
|
|
} else {
|
|
echo "<td> </td>";
|
|
}
|
|
}
|
|
|
|
if (!$display_entities) {
|
|
if ($this->can_sort
|
|
&& !$last
|
|
&& $canedit) {
|
|
echo "<td>";
|
|
Html::showSimpleForm($target, ['action' => 'down',
|
|
'condition' => $active_condition], '',
|
|
['type' => $this->fields["sub_type"],
|
|
'id' => $this->fields["id"]],
|
|
$CFG_GLPI["root_doc"]."/pics/deplier_down.png");
|
|
echo "</td>";
|
|
} else {
|
|
echo "<td> </td>";
|
|
}
|
|
}
|
|
echo "</tr>\n";
|
|
}
|
|
|
|
|
|
/**
|
|
* @see CommonDBTM::prepareInputForAdd()
|
|
**/
|
|
function prepareInputForAdd($input) {
|
|
|
|
// Before adding, add the ranking of the new rule
|
|
$input["ranking"] = $input['ranking'] ?? $this->getNextRanking();
|
|
//If no uuid given, generate a new one
|
|
if (!isset($input['uuid'])) {
|
|
$input["uuid"] = self::getUuid();
|
|
}
|
|
|
|
if ($this->getType() == 'Rule' && !isset($input['sub_type'])) {
|
|
\Toolbox::logError('Sub type not specified creating a new rule');
|
|
return false;
|
|
}
|
|
|
|
if (!isset($input['sub_type'])) {
|
|
$input['sub_type'] = $this->getType();
|
|
} else if ($this->getType() != 'Rule' && $input['sub_type'] != $this->getType()) {
|
|
\Toolbox::logWarning(
|
|
sprintf(
|
|
'Creating a %s rule with %s subtype.',
|
|
$this->getType(),
|
|
$input['sub_type']
|
|
)
|
|
);
|
|
}
|
|
|
|
return $input;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the next ranking for a specified rule
|
|
**/
|
|
function getNextRanking() {
|
|
global $DB;
|
|
|
|
$iterator = $DB->request([
|
|
'SELECT' => ['MAX' => 'ranking AS rank'],
|
|
'FROM' => self::getTable(),
|
|
'WHERE' => ['sub_type' => $this->getType()]
|
|
]);
|
|
|
|
if (count($iterator)) {
|
|
$data = $iterator->next();
|
|
return $data["rank"] + 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* Show the minimal form for the action rule
|
|
*
|
|
* @param $fields datas used to display the action
|
|
* @param $canedit can edit the actions rule ?
|
|
* @param $rand random value of the form
|
|
**/
|
|
function showMinimalActionForm($fields, $canedit, $rand) {
|
|
global $CFG_GLPI;
|
|
|
|
$edit = ($canedit ? "style='cursor:pointer' onClick=\"viewEditAction".
|
|
$fields[$this->rules_id_field].$fields["id"]."$rand();\""
|
|
: '');
|
|
echo "<tr class='tab_bg_1'>";
|
|
if ($canedit) {
|
|
echo "<td width='10'>";
|
|
Html::showMassiveActionCheckBox($this->ruleactionclass, $fields["id"]);
|
|
echo "\n<script type='text/javascript' >\n";
|
|
echo "function viewEditAction". $fields[$this->rules_id_field].$fields["id"]."$rand() {\n";
|
|
$params = ['type' => $this->ruleactionclass,
|
|
'parenttype' => $this->getType(),
|
|
$this->rules_id_field => $fields[$this->rules_id_field],
|
|
'id' => $fields["id"]];
|
|
Ajax::updateItemJsCode("viewaction" . $fields[$this->rules_id_field] . "$rand",
|
|
$CFG_GLPI["root_doc"]."/ajax/viewsubitem.php", $params);
|
|
echo "};";
|
|
echo "</script>\n";
|
|
echo "</td>";
|
|
}
|
|
echo $this->getMinimalActionText($fields, $edit);
|
|
echo "</tr>\n";
|
|
}
|
|
|
|
|
|
/**
|
|
* Show preview result of a rule
|
|
*
|
|
* @param $target where to go if action
|
|
* @param $input input data array
|
|
* @param $params params used (see addSpecificParamsForPreview)
|
|
**/
|
|
function showRulePreviewResultsForm($target, $input, $params) {
|
|
|
|
$actions = $this->getAllActions();
|
|
$check_results = [];
|
|
$output = [];
|
|
|
|
//Test all criteria, without stopping at the first good one
|
|
$this->testCriterias($input, $check_results);
|
|
//Process the rule
|
|
$this->process($input, $output, $params);
|
|
if (!$criteria = getItemForItemtype($this->rulecriteriaclass)) {
|
|
return;
|
|
}
|
|
|
|
echo "<div class='spaced'>";
|
|
echo "<table class='tab_cadrehov'>";
|
|
echo "<tr><th colspan='4'>" . __('Result details') . "</th></tr>";
|
|
|
|
echo "<tr class='tab_bg_2'>";
|
|
echo "<td class='center b'>"._n('Criterion', 'Criteria', 1)."</td>";
|
|
echo "<td class='center b'>".__('Condition')."</td>";
|
|
echo "<td class='center b'>".__('Reason')."</td>";
|
|
echo "<td class='center b'>"._n('Validation', 'Validations', 1)."</td>";
|
|
echo "</tr>\n";
|
|
|
|
foreach ($check_results as $ID => $criteria_result) {
|
|
echo "<tr class='tab_bg_1'>";
|
|
$criteria->getFromDB($criteria_result["id"]);
|
|
echo $this->getMinimalCriteriaText($criteria->fields);
|
|
if ($criteria->fields['condition'] != self::PATTERN_FIND) {
|
|
echo "<td class='b'>".Dropdown::getYesNo($criteria_result["result"])."</td></tr>\n";
|
|
} else {
|
|
echo "<td class='b'>".Dropdown::EMPTY_VALUE."</td></tr>\n";
|
|
}
|
|
}
|
|
echo "</table></div>";
|
|
|
|
$global_result = (isset($output["_rule_process"])?1:0);
|
|
|
|
echo "<div class='spaced'>";
|
|
echo "<table class='tab_cadrehov'>";
|
|
echo "<tr><th colspan='2'>" . __('Rule results') . "</th></tr>";
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td class='center b'>"._n('Validation', 'Validations', 1)."</td><td>";
|
|
echo Dropdown::getYesNo($global_result)."</td></tr>";
|
|
|
|
$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>";
|
|
if (isset($actions[$criteria]['type'])) {
|
|
$actiontype = $actions[$criteria]['type'];
|
|
} else {
|
|
$actiontype ='';
|
|
}
|
|
echo "<td>".$this->getActionValue($criteria, $actiontype, $value);
|
|
echo "</td></tr>\n";
|
|
}
|
|
}
|
|
|
|
//If a regular expression was used, and matched, display the results
|
|
if (count($this->regex_results)) {
|
|
echo "<tr class='tab_bg_2'>";
|
|
echo "<td>".__('Result of the regular expression')."</td>";
|
|
echo "<td>";
|
|
if (!empty($this->regex_results[0])) {
|
|
echo "<table class='tab_cadre'>";
|
|
echo "<tr><th>".__('Key')."</th><th>".__('Value')."</th></tr>";
|
|
foreach ($this->regex_results[0] as $key => $value) {
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>$key</td><td>$value</td></tr>";
|
|
}
|
|
echo "</table>";
|
|
}
|
|
echo "</td></tr>\n";
|
|
}
|
|
echo "</tr>\n";
|
|
echo "</table></div>";
|
|
}
|
|
|
|
|
|
/**
|
|
* Show the minimal form for the criteria rule
|
|
*
|
|
* @param $fields datas used to display the criteria
|
|
* @param $canedit can edit the criteria rule?
|
|
* @param $rand random value of the form
|
|
**/
|
|
function showMinimalCriteriaForm($fields, $canedit, $rand) {
|
|
global $CFG_GLPI;
|
|
|
|
$edit = ($canedit ? "style='cursor:pointer' onClick=\"viewEditCriteria".
|
|
$fields[$this->rules_id_field].$fields["id"]."$rand();\""
|
|
: '');
|
|
echo "<tr class='tab_bg_1' >";
|
|
if ($canedit) {
|
|
echo "<td width='10'>";
|
|
Html::showMassiveActionCheckBox($this->rulecriteriaclass, $fields["id"]);
|
|
echo "\n<script type='text/javascript' >\n";
|
|
echo "function viewEditCriteria". $fields[$this->rules_id_field].$fields["id"]."$rand() {\n";
|
|
$params = ['type' => $this->rulecriteriaclass,
|
|
'parenttype' => $this->getType(),
|
|
$this->rules_id_field => $fields[$this->rules_id_field],
|
|
'id' => $fields["id"]];
|
|
Ajax::updateItemJsCode("viewcriteria" . $fields[$this->rules_id_field] . "$rand",
|
|
$CFG_GLPI["root_doc"]."/ajax/viewsubitem.php", $params);
|
|
echo "};";
|
|
echo "</script>\n";
|
|
echo "</td>";
|
|
}
|
|
|
|
echo $this->getMinimalCriteriaText($fields, $edit);
|
|
echo "</tr>\n";
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $fields
|
|
* @param $addtotd (default '')
|
|
**/
|
|
function getMinimalCriteriaText($fields, $addtotd = '') {
|
|
|
|
$text = "<td $addtotd>" . $this->getCriteriaName($fields["criteria"]) . "</td>";
|
|
$text .= "<td $addtotd>" . RuleCriteria::getConditionByID($fields["condition"],
|
|
get_class($this),
|
|
$fields["criteria"])."</td>";
|
|
$text .= "<td $addtotd>" . $this->getCriteriaDisplayPattern($fields["criteria"],
|
|
$fields["condition"],
|
|
$fields["pattern"]) . "</td>";
|
|
return $text;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $fields
|
|
* @param $addtotd (default '')
|
|
**/
|
|
function getMinimalActionText($fields, $addtotd = '') {
|
|
|
|
$text = "<td $addtotd>" . $this->getActionName($fields["field"]) . "</td>";
|
|
$text .= "<td $addtotd>" . RuleAction::getActionByID($fields["action_type"]) . "</td>";
|
|
if (isset($fields["value"])) {
|
|
$text .= "<td $addtotd>" . $this->getActionValue($fields["field"], $fields['action_type'],
|
|
$fields["value"]) . "</td>";
|
|
} else {
|
|
$text .= "<td $addtotd> </td>";
|
|
}
|
|
return $text;
|
|
}
|
|
|
|
|
|
/**
|
|
* Return a value associated with a pattern associated to a criteria to display it
|
|
*
|
|
* @param $ID the given criteria
|
|
* @param $condition condition used
|
|
* @param $pattern the pattern
|
|
**/
|
|
function getCriteriaDisplayPattern($ID, $condition, $pattern) {
|
|
|
|
if (($condition == self::PATTERN_EXISTS)
|
|
|| ($condition == self::PATTERN_DOES_NOT_EXISTS)
|
|
|| ($condition == self::PATTERN_FIND)) {
|
|
return __('Yes');
|
|
|
|
} else if (in_array($condition, [self::PATTERN_IS, self::PATTERN_IS_NOT,
|
|
self::PATTERN_NOT_UNDER, self::PATTERN_UNDER])) {
|
|
$crit = $this->getCriteria($ID);
|
|
|
|
if (isset($crit['type'])) {
|
|
switch ($crit['type']) {
|
|
case "yesonly" :
|
|
case "yesno" :
|
|
return Dropdown::getYesNo($pattern);
|
|
|
|
case "dropdown" :
|
|
$addentity = Dropdown::getDropdownName($crit["table"], $pattern);
|
|
if ($this->isEntityAssign()) {
|
|
$itemtype = getItemTypeForTable($crit["table"]);
|
|
$item = getItemForItemtype($itemtype);
|
|
if ($item
|
|
&& $item->getFromDB($pattern)
|
|
&& $item->isEntityAssign()) {
|
|
$addentity = sprintf(__('%1$s (%2$s)'), $addentity,
|
|
Dropdown::getDropdownName('glpi_entities',
|
|
$item->getEntityID()));
|
|
}
|
|
}
|
|
$tmp = $addentity;
|
|
return (($tmp == ' ') ? NOT_AVAILABLE : $tmp);
|
|
|
|
case "dropdown_users" :
|
|
return getUserName($pattern);
|
|
|
|
case "dropdown_assets_itemtype" :
|
|
case "dropdown_tracking_itemtype" :
|
|
if ($item = getItemForItemtype($pattern)) {
|
|
return $item->getTypeName(1);
|
|
}
|
|
if (empty($pattern)) {
|
|
return __('General');
|
|
}
|
|
break;
|
|
|
|
case "dropdown_status" :
|
|
return Ticket::getStatus($pattern);
|
|
|
|
case "dropdown_priority" :
|
|
return Ticket::getPriorityName($pattern);
|
|
|
|
case "dropdown_urgency" :
|
|
return Ticket::getUrgencyName($pattern);
|
|
|
|
case "dropdown_impact" :
|
|
return Ticket::getImpactName($pattern);
|
|
|
|
case "dropdown_tickettype" :
|
|
return Ticket::getTicketTypeName($pattern);
|
|
}
|
|
}
|
|
}
|
|
if ($result = $this->getAdditionalCriteriaDisplayPattern($ID, $condition, $pattern)) {
|
|
return $result;
|
|
}
|
|
return $pattern;
|
|
}
|
|
|
|
|
|
/**
|
|
* Used to get specific criteria patterns
|
|
*
|
|
* @param $ID the given criteria
|
|
* @param $condition condition used
|
|
* @param $pattern the pattern
|
|
*
|
|
* @return a value associated with the criteria, or false otherwise
|
|
**/
|
|
function getAdditionalCriteriaDisplayPattern($ID, $condition, $pattern) {
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Display item used to select a pattern for a criteria
|
|
*
|
|
* @param $name criteria name
|
|
* @param $ID the given criteria
|
|
* @param $condition condition used
|
|
* @param $value the pattern (default '')
|
|
* @param $test Is to test rule ? (false by default)
|
|
**/
|
|
function displayCriteriaSelectPattern($name, $ID, $condition, $value = "", $test = false) {
|
|
global $CFG_GLPI;
|
|
|
|
$crit = $this->getCriteria($ID);
|
|
$display = false;
|
|
$tested = false;
|
|
|
|
if (isset($crit['type'])
|
|
&& ($test
|
|
|| in_array($condition, [self::PATTERN_IS, self::PATTERN_IS_NOT,
|
|
self::PATTERN_NOT_UNDER, self::PATTERN_UNDER]))) {
|
|
|
|
$tested = true;
|
|
switch ($crit['type']) {
|
|
case "yesonly" :
|
|
Dropdown::showYesNo($name, $crit['table'], 0);
|
|
$display = true;
|
|
break;
|
|
|
|
case "yesno" :
|
|
Dropdown::showYesNo($name, $value);
|
|
$display = true;
|
|
break;
|
|
|
|
case "dropdown" :
|
|
$param = ['name' => $name,
|
|
'value' => $value];
|
|
if (isset($crit['condition'])) {
|
|
$param['condition'] = $crit['condition'];
|
|
}
|
|
Dropdown::show(getItemTypeForTable($crit['table']), $param);
|
|
|
|
$display = true;
|
|
break;
|
|
|
|
case "dropdown_users" :
|
|
User::dropdown(['value' => $value,
|
|
'name' => $name,
|
|
'right' => 'all']);
|
|
$display = true;
|
|
break;
|
|
|
|
case "dropdown_tracking_itemtype" :
|
|
Dropdown::showItemTypes($name, array_keys(Ticket::getAllTypesForHelpdesk()));
|
|
$display = true;
|
|
break;
|
|
|
|
case "dropdown_assets_itemtype" :
|
|
Dropdown::showItemTypes($name, $CFG_GLPI['asset_types'], ['value' => $value]);
|
|
$display = true;
|
|
break;
|
|
|
|
case "dropdown_import_type" :
|
|
RuleAsset::dropdownImportType($name, $value);
|
|
$display = true;
|
|
break;
|
|
|
|
case "dropdown_urgency" :
|
|
Ticket::dropdownUrgency(['name' => $name,
|
|
'value' => $value]);
|
|
$display = true;
|
|
break;
|
|
|
|
case "dropdown_impact" :
|
|
Ticket::dropdownImpact(['name' => $name,
|
|
'value' => $value]);
|
|
$display = true;
|
|
break;
|
|
|
|
case "dropdown_priority" :
|
|
Ticket::dropdownPriority(['name' => $name,
|
|
'value' => $value,
|
|
'withmajor' => true]);
|
|
$display = true;
|
|
break;
|
|
|
|
case "dropdown_status" :
|
|
Ticket::dropdownStatus(['name' => $name,
|
|
'value' => $value]);
|
|
$display = true;
|
|
break;
|
|
|
|
case "dropdown_tickettype" :
|
|
Ticket::dropdownType($name, ['value' => $value]);
|
|
$display = true;
|
|
break;
|
|
|
|
default:
|
|
$tested = false;
|
|
break;
|
|
}
|
|
}
|
|
//Not a standard condition
|
|
if (!$tested) {
|
|
$display = $this->displayAdditionalRuleCondition($condition, $crit, $name, $value, $test);
|
|
}
|
|
|
|
if (($condition == self::PATTERN_EXISTS)
|
|
|| ($condition == self::PATTERN_DOES_NOT_EXISTS)) {
|
|
echo "<input type='hidden' name='$name' value='1'>";
|
|
$display = true;
|
|
}
|
|
|
|
if (!$display
|
|
&& ($rc = getItemForItemtype($this->rulecriteriaclass))) {
|
|
Html::autocompletionTextField($rc, "pattern", ['name' => $name,
|
|
'value' => $value,
|
|
'size' => 70]);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Return a "display" value associated with a pattern associated to a criteria
|
|
*
|
|
* @param $ID the given action
|
|
* @param $type the type of action
|
|
* @param $value the value
|
|
**/
|
|
function getActionValue($ID, $type, $value) {
|
|
|
|
$action = $this->getAction($ID);
|
|
if (isset($action['type'])) {
|
|
|
|
switch ($action['type']) {
|
|
case "dropdown" :
|
|
if ($type=='defaultfromuser' || $type=='fromuser' || $type=='fromitem') {
|
|
return Dropdown::getYesNo($value);
|
|
}
|
|
// $type == assign
|
|
$tmp = Dropdown::getDropdownName($action["table"], $value);
|
|
return (($tmp == ' ') ? NOT_AVAILABLE : $tmp);
|
|
|
|
case "dropdown_status" :
|
|
return Ticket::getStatus($value);
|
|
|
|
case "dropdown_assign" :
|
|
case "dropdown_users" :
|
|
case "dropdown_users_validate" :
|
|
return getUserName($value);
|
|
|
|
case "dropdown_groups_validate" :
|
|
return Dropdown::getDropdownName('glpi_groups', $value);
|
|
|
|
case "dropdown_validation_percent" :
|
|
return Dropdown::getValueWithUnit($value, '%');
|
|
|
|
case "yesonly" :
|
|
case "yesno" :
|
|
return Dropdown::getYesNo($value);
|
|
|
|
case "dropdown_urgency" :
|
|
return Ticket::getUrgencyName($value);
|
|
|
|
case "dropdown_impact" :
|
|
return Ticket::getImpactName($value);
|
|
|
|
case "dropdown_priority" :
|
|
return Ticket::getPriorityName($value);
|
|
|
|
case "dropdown_tickettype" :
|
|
return Ticket::getTicketTypeName($value);
|
|
|
|
case "dropdown_management" :
|
|
return Dropdown::getGlobalSwitch($value);
|
|
|
|
default :
|
|
return $this->displayAdditionRuleActionValue($value);
|
|
}
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
|
|
/**
|
|
* Return a value associated with a pattern associated to a criteria to display it
|
|
*
|
|
* @param $ID the given criteria
|
|
* @param $condition condition used
|
|
* @param $value the pattern
|
|
**/
|
|
function getCriteriaValue($ID, $condition, $value) {
|
|
|
|
if (!in_array($condition, [self::PATTERN_DOES_NOT_EXISTS, self::PATTERN_EXISTS,
|
|
self::PATTERN_IS, self::PATTERN_IS_NOT,
|
|
self::PATTERN_NOT_UNDER, self::PATTERN_UNDER])) {
|
|
$crit = $this->getCriteria($ID);
|
|
if (isset($crit['type'])) {
|
|
|
|
switch ($crit['type']) {
|
|
case "dropdown" :
|
|
$tmp = Dropdown::getDropdownName($crit["table"], $value, false, false);
|
|
//$tmp = Dropdown::getDropdownName($crit["table"], $value);
|
|
// return empty string to be able to check if set
|
|
if ($tmp == ' ') {
|
|
return '';
|
|
}
|
|
return $tmp;
|
|
|
|
case "dropdown_assign" :
|
|
case "dropdown_users" :
|
|
return getUserName($value);
|
|
|
|
case "yesonly" :
|
|
case "yesno" :
|
|
return Dropdown::getYesNo($value);
|
|
|
|
case "dropdown_impact" :
|
|
return Ticket::getImpactName($value);
|
|
|
|
case "dropdown_urgency" :
|
|
return Ticket::getUrgencyName($value);
|
|
|
|
case "dropdown_priority" :
|
|
return Ticket::getPriorityName($value);
|
|
|
|
}
|
|
}
|
|
}
|
|
return $value;
|
|
}
|
|
|
|
|
|
/**
|
|
* Function used to display type specific criteria during rule's preview
|
|
*
|
|
* @param $fields fields values
|
|
**/
|
|
function showSpecificCriteriasForPreview($fields) {
|
|
}
|
|
|
|
|
|
/**
|
|
* Function used to add specific params before rule processing
|
|
*
|
|
* @param $params parameters
|
|
**/
|
|
function addSpecificParamsForPreview($params) {
|
|
return $params;
|
|
}
|
|
|
|
|
|
/**
|
|
* Criteria form used to preview rule
|
|
*
|
|
* @param $target target of the form
|
|
* @param $rules_id ID of the rule
|
|
**/
|
|
function showRulePreviewCriteriasForm($target, $rules_id) {
|
|
$criteria = $this->getAllCriteria();
|
|
|
|
if ($this->getRuleWithCriteriasAndActions($rules_id, 1, 0)) {
|
|
echo "<form name='testrule_form' id='testrule_form' method='post' action='$target'>\n";
|
|
echo "<div class='spaced'>";
|
|
echo "<table class='tab_cadre_fixe'>";
|
|
echo "<tr><th colspan='3'>" . _n('Criterion', 'Criteria', Session::getPluralNumber()) . "</th></tr>";
|
|
|
|
$type_match = (($this->fields["match"] == self::AND_MATCHING) ?__('and') :__('or'));
|
|
$already_displayed = [];
|
|
$first = true;
|
|
|
|
//Brower all criteria
|
|
foreach ($this->criterias as $criterion) {
|
|
|
|
//Look for the criteria in the field of already displayed criteria :
|
|
//if present, don't display it again
|
|
if (!in_array($criterion->fields["criteria"], $already_displayed)) {
|
|
$already_displayed[] = $criterion->fields["criteria"];
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>";
|
|
|
|
if ($first) {
|
|
echo " ";
|
|
$first = false;
|
|
} else {
|
|
echo $type_match;
|
|
}
|
|
|
|
echo "</td>";
|
|
$criteria_constants = $criteria[$criterion->fields["criteria"]];
|
|
echo "<td>".$criteria_constants["name"]."</td>";
|
|
echo "<td>";
|
|
$value = "";
|
|
if (isset($_POST[$criterion->fields["criteria"]])) {
|
|
$value = $_POST[$criterion->fields["criteria"]];
|
|
}
|
|
|
|
$this->displayCriteriaSelectPattern($criterion->fields['criteria'],
|
|
$criterion->fields['criteria'],
|
|
$criterion->fields['condition'], $value, true);
|
|
echo "</td></tr>\n";
|
|
}
|
|
}
|
|
$this->showSpecificCriteriasForPreview($_POST);
|
|
|
|
echo "<tr><td class='tab_bg_2 center' colspan='3'>";
|
|
echo "<input type='submit' name='test_rule' value=\""._sx('button', 'Test')."\"
|
|
class='submit'>";
|
|
echo "<input type='hidden' name='".$this->rules_id_field."' value='$rules_id'>";
|
|
echo "<input type='hidden' name='sub_type' value='" . $this->getType() . "'>";
|
|
echo "</td></tr>\n";
|
|
echo "</table></div>\n";
|
|
Html::closeForm();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $output
|
|
**/
|
|
function preProcessPreviewResults($output) {
|
|
global $PLUGIN_HOOKS;
|
|
|
|
if (isset($PLUGIN_HOOKS['use_rules'])) {
|
|
$params['criterias_results'] = $this->criterias_results;
|
|
$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, "preProcessRulePreviewResults",
|
|
['output' => $output,
|
|
'params' => $params]);
|
|
if (is_array($results)) {
|
|
foreach ($results as $id => $result) {
|
|
$output[$id] = $result;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $output;
|
|
}
|
|
|
|
|
|
/**
|
|
* Dropdown rules for a defined sub_type of rule
|
|
*
|
|
* @param $options array of possible options:
|
|
* - name : string / name of the select (default is depending itemtype)
|
|
* - sub_type : integer / sub_type of rule
|
|
**/
|
|
static function dropdown($options = []) {
|
|
$p['sub_type'] = '';
|
|
$p['name'] = 'rules_id';
|
|
$p['entity'] = '';
|
|
$p['condition'] = 0;
|
|
|
|
if (is_array($options) && count($options)) {
|
|
foreach ($options as $key => $val) {
|
|
$p[$key] = $val;
|
|
}
|
|
}
|
|
|
|
if ($p['sub_type'] == '') {
|
|
return false;
|
|
}
|
|
|
|
$conditions = [
|
|
'sub_type' => $p['sub_type']
|
|
];
|
|
if ($p['condition'] > 0) {
|
|
$conditions['condition'] = ['&', (int)$p['condition']];
|
|
}
|
|
|
|
$p['condition'] = $conditions;
|
|
return Dropdown::show($p['sub_type'], $p);
|
|
}
|
|
|
|
|
|
/**
|
|
* @since 0.84
|
|
**/
|
|
function getAllCriteria() {
|
|
|
|
return self::doHookAndMergeResults("getRuleCriteria", $this->getCriterias(),
|
|
$this->getType());
|
|
}
|
|
|
|
|
|
function getCriterias() {
|
|
return [];
|
|
}
|
|
|
|
|
|
/**
|
|
* @since 0.84
|
|
* @return array
|
|
*/
|
|
function getAllActions() {
|
|
return self::doHookAndMergeResults("getRuleActions", $this->getActions(), $this->getType());
|
|
}
|
|
|
|
|
|
function getActions() {
|
|
return [];
|
|
}
|
|
|
|
|
|
/**
|
|
* Execute a hook if necessary and merge results
|
|
*
|
|
* @since 0.84
|
|
*
|
|
* @param $hook the hook to execute
|
|
* @param $params array input parameters
|
|
* @param $itemtype (default '')
|
|
*
|
|
* @return input parameters merged with hook parameters
|
|
**/
|
|
static function doHookAndMergeResults($hook, $params = [], $itemtype = '') {
|
|
global $PLUGIN_HOOKS;
|
|
|
|
if (empty($itemtype)) {
|
|
$itemtype = static::getType();
|
|
}
|
|
|
|
//Agregate all plugins criteria for this rules engine
|
|
$toreturn = $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($itemtype, $val)) {
|
|
$results = Plugin::doOneHook($plugin, $hook, ['rule_itemtype' => $itemtype,
|
|
'values' => $params]);
|
|
if (is_array($results)) {
|
|
foreach ($results as $id => $result) {
|
|
$toreturn[$id] = $result;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $toreturn;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $sub_type
|
|
**/
|
|
static function getActionsByType($sub_type) {
|
|
|
|
if ($rule = getItemForItemtype($sub_type)) {
|
|
return $rule->getAllActions();
|
|
}
|
|
return [];
|
|
}
|
|
|
|
|
|
/**
|
|
* Return all rules from database
|
|
*
|
|
* @param $crit array of criteria (at least, 'field' and 'value')
|
|
*
|
|
* @return array of Rule objects
|
|
**/
|
|
function getRulesForCriteria($crit) {
|
|
global $DB;
|
|
|
|
$rules = [];
|
|
|
|
/// TODO : not working for SLALevels : no sub_type
|
|
|
|
//Get all the rules whose sub_type is $sub_type and entity is $ID
|
|
$query = [
|
|
'SELECT' => $this->getTable() . '.id',
|
|
'FROM' => [
|
|
getTableForItemType($this->ruleactionclass),
|
|
$this->getTable()
|
|
],
|
|
'WHERE' => [
|
|
getTableForItemType($this->ruleactionclass).".".$this->rules_id_field => new \QueryExpression(DBmysql::quoteName($this->getTable().'.id')),
|
|
$this->getTable().'.sub_type' => get_class($this)
|
|
|
|
]
|
|
];
|
|
|
|
foreach ($crit as $field => $value) {
|
|
$query['WHERE'][getTableForItemType($this->ruleactionclass).'.'.$field] = $value;
|
|
}
|
|
|
|
$iterator = $DB->request($query);
|
|
|
|
while ($rule = $iterator->next()) {
|
|
$affect_rule = new Rule();
|
|
$affect_rule->getRuleWithCriteriasAndActions($rule["id"], 0, 1);
|
|
$rules[] = $affect_rule;
|
|
}
|
|
return $rules;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $ID
|
|
**/
|
|
function showNewRuleForm($ID) {
|
|
|
|
echo "<form method='post' action='".Toolbox::getItemTypeFormURL('Entity')."'>";
|
|
echo "<table class='tab_cadre_fixe'>";
|
|
echo "<tr><th colspan='7'>" . $this->getTitle() . "</th></tr>\n";
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>".__('Name') . "</td><td>";
|
|
Html::autocompletionTextField($this, "name", ['value' => '',
|
|
'size' => 33]);
|
|
echo "</td><td>".__('Description') . "</td><td>";
|
|
Html::autocompletionTextField($this, "description", ['value' => '',
|
|
'size' => 33]);
|
|
echo "</td><td>".__('Logical operator') . "</td><td>";
|
|
$this->dropdownRulesMatch();
|
|
echo "</td><td class='tab_bg_2 center'>";
|
|
echo "<input type=hidden name='sub_type' value='".get_class($this)."'>";
|
|
echo "<input type=hidden name='entities_id' value='-1'>";
|
|
echo "<input type=hidden name='affectentity' value='$ID'>";
|
|
echo "<input type=hidden name='_method' value='AddRule'>";
|
|
echo "<input type='submit' name='execute' value=\""._sx('button', 'Add')."\" class='submit'>";
|
|
echo "</td></tr>\n";
|
|
echo "</table>";
|
|
Html::closeForm();
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $item
|
|
**/
|
|
function showAndAddRuleForm($item) {
|
|
|
|
$rand = mt_rand();
|
|
$canedit = self::canUpdate();
|
|
|
|
if ($canedit
|
|
&& ($item->getType() == 'Entity')) {
|
|
$this->showNewRuleForm($item->getField('id'));
|
|
}
|
|
|
|
//Get all rules and actions
|
|
$crit = ['field' => getForeignKeyFieldForTable($item->getTable()),
|
|
'value' => $item->getField('id')];
|
|
|
|
$rules = $this->getRulesForCriteria($crit);
|
|
$nb = count($rules);
|
|
echo "<div class='spaced'>";
|
|
|
|
if (!$nb) {
|
|
echo "<table class='tab_cadre_fixehov'>";
|
|
echo "<tr><th>" . __('No item found') . "</th>";
|
|
echo "</tr>\n";
|
|
echo "</table>\n";
|
|
|
|
} else {
|
|
if ($canedit) {
|
|
Html::openMassiveActionsForm('mass'.get_called_class().$rand);
|
|
$massiveactionparams
|
|
= ['num_displayed'
|
|
=> min($_SESSION['glpilist_limit'], $nb),
|
|
'specific_actions'
|
|
=> ['update' => _x('button', 'Update'),
|
|
'purge' => _x('button', 'Delete permanently')]];
|
|
// 'extraparams'
|
|
// => array('rule_class_name' => $this->getRuleClassName()));
|
|
Html::showMassiveActions($massiveactionparams);
|
|
}
|
|
echo "<table class='tab_cadre_fixehov'>";
|
|
$header_begin = "<tr>";
|
|
$header_top = '';
|
|
$header_bottom = '';
|
|
$header_end = '';
|
|
if ($canedit) {
|
|
$header_begin .= "<th width='10'>";
|
|
$header_top .= Html::getCheckAllAsCheckbox('mass'.get_called_class().$rand);
|
|
$header_bottom .= Html::getCheckAllAsCheckbox('mass'.get_called_class().$rand);
|
|
$header_end .= "</th>";
|
|
}
|
|
$header_end .= "<th>" . $this->getTitle() . "</th>";
|
|
$header_end .= "<th>" . __('Description') . "</th>";
|
|
$header_end .= "<th>" . __('Active') . "</th>";
|
|
$header_end .= "</tr>\n";
|
|
echo $header_begin.$header_top.$header_end;
|
|
|
|
Session::initNavigateListItems(get_class($this),
|
|
//TRANS: %1$s is the itemtype name,
|
|
// %2$s is the name of the item (used for headings of a list)
|
|
sprintf(__('%1$s = %2$s'),
|
|
$item->getTypeName(1), $item->getName()));
|
|
|
|
foreach ($rules as $rule) {
|
|
Session::addToNavigateListItems(get_class($this), $rule->fields["id"]);
|
|
echo "<tr class='tab_bg_1'>";
|
|
|
|
if ($canedit) {
|
|
echo "<td width='10'>";
|
|
Html::showMassiveActionCheckBox(__CLASS__, $rule->fields["id"]);
|
|
echo "</td>";
|
|
echo "<td><a href='".$this->getFormURLWithID($rule->fields["id"])
|
|
. "&onglet=1'>" .$rule->fields["name"] ."</a></td>";
|
|
|
|
} else {
|
|
echo "<td>" . $rule->fields["name"] . "</td>";
|
|
}
|
|
|
|
echo "<td>" . $rule->fields["description"] . "</td>";
|
|
echo "<td>" . Dropdown::getYesNo($rule->fields["is_active"]) . "</td>";
|
|
echo "</tr>\n";
|
|
}
|
|
echo $header_begin.$header_bottom.$header_end;
|
|
echo "</table>\n";
|
|
|
|
if ($canedit) {
|
|
$massiveactionparams['ontop'] = false;
|
|
Html::showMassiveActions($massiveactionparams);
|
|
Html::closeForm();
|
|
}
|
|
}
|
|
echo "</div>";
|
|
}
|
|
|
|
|
|
/**
|
|
* @see CommonGLPI::defineTabs()
|
|
**/
|
|
function defineTabs($options = []) {
|
|
|
|
$ong = [];
|
|
$this->addDefaultFormTab($ong);
|
|
$this->addStandardTab(__CLASS__, $ong, $options);
|
|
$this->addStandardTab('Log', $ong, $options);
|
|
|
|
return $ong;
|
|
}
|
|
|
|
|
|
/**
|
|
* Add more criteria specific to this type of rule
|
|
**/
|
|
static function addMoreCriteria() {
|
|
return [];
|
|
}
|
|
|
|
|
|
/**
|
|
* Add more actions specific to this type of rule
|
|
*
|
|
* @param $value
|
|
**/
|
|
function displayAdditionRuleActionValue($value) {
|
|
return $value;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $condition
|
|
* @param $criteria
|
|
* @param $name
|
|
* @param $value
|
|
* @param $test (false by default)
|
|
**/
|
|
function displayAdditionalRuleCondition($condition, $criteria, $name, $value, $test = false) {
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $action array
|
|
* @param $value value to display (default '')
|
|
**/
|
|
function displayAdditionalRuleAction(array $action, $value = '') {
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Clean Rule with Action or Criteria linked to an item
|
|
*
|
|
* @param $item Object
|
|
* @param $field string name (default is FK to item)
|
|
* @param $ruleitem object (instance of Rules of SlaLevel)
|
|
* @param $table string (glpi_ruleactions, glpi_rulescriterias or glpi_slalevelcriterias)
|
|
* @param $valfield string (value or pattern)
|
|
* @param $fieldfield string (criteria of field)
|
|
**/
|
|
private static function cleanForItemActionOrCriteria($item, $field, $ruleitem, $table,
|
|
$valfield, $fieldfield) {
|
|
global $DB;
|
|
|
|
$fieldid = getForeignKeyFieldForTable($ruleitem->getTable());
|
|
|
|
if (empty($field)) {
|
|
$field = getForeignKeyFieldForTable($item->getTable());
|
|
}
|
|
|
|
if (isset($item->input['_replace_by']) && ($item->input['_replace_by'] > 0)) {
|
|
$DB->update(
|
|
$table, [
|
|
$valfield => $item->input['_replace_by']
|
|
], [
|
|
$valfield => $item->getField('id'),
|
|
$fieldfield => ['LIKE', $field]
|
|
]
|
|
);
|
|
} else {
|
|
$iterator = $DB->request([
|
|
'SELECT' => [$fieldid],
|
|
'FROM' => $table,
|
|
'WHERE' => [
|
|
$valfield => $item->getField('id'),
|
|
$fieldfield => ['LIKE', $field]
|
|
]
|
|
]);
|
|
|
|
if (count($iterator) > 0) {
|
|
$input['is_active'] = 0;
|
|
|
|
while ($data = $iterator->next()) {
|
|
$input['id'] = $data[$fieldid];
|
|
$ruleitem->update($input);
|
|
}
|
|
Session::addMessageAfterRedirect(__('Rules using the object have been disabled.'),
|
|
true);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Clean Rule with Action is assign to an item
|
|
*
|
|
* @param $item Object
|
|
* @param $field string name (default is FK to item) (default '')
|
|
**/
|
|
static function cleanForItemAction($item, $field = '') {
|
|
|
|
self::cleanForItemActionOrCriteria($item, $field,
|
|
new self(), 'glpi_ruleactions', 'value', 'field');
|
|
|
|
self::cleanForItemActionOrCriteria($item, $field,
|
|
new SlaLevel(), 'glpi_slalevelactions', 'value', 'field');
|
|
|
|
self::cleanForItemActionOrCriteria($item, $field,
|
|
new OlaLevel(), 'glpi_olalevelactions', 'value', 'field');
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* Clean Rule with Criteria on an item
|
|
*
|
|
* @param $item Object
|
|
* @param $field string name (default is FK to item) (default '')
|
|
**/
|
|
static function cleanForItemCriteria($item, $field = '') {
|
|
|
|
self::cleanForItemActionOrCriteria($item, $field,
|
|
new self(), 'glpi_rulecriterias', 'pattern', 'criteria');
|
|
}
|
|
|
|
|
|
/**
|
|
* @see CommonGLPI::getTabNameForItem()
|
|
**/
|
|
function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) {
|
|
|
|
if (!$withtemplate) {
|
|
$nb = 0;
|
|
switch ($item->getType()) {
|
|
case 'Entity' :
|
|
if ($_SESSION['glpishow_count_on_tabs']) {
|
|
$types = [];
|
|
$collection = new RuleRightCollection();
|
|
if ($collection->canList()) {
|
|
$types[] = 'RuleRight';
|
|
}
|
|
$collection = new RuleImportEntityCollection();
|
|
if ($collection->canList()) {
|
|
$types[] = 'RuleImportEntity';
|
|
}
|
|
$collection = new RuleMailCollectorCollection();
|
|
if ($collection->canList()) {
|
|
$types[] = 'RuleMailCollector';
|
|
}
|
|
if (count($types)) {
|
|
$nb = countElementsInTable(
|
|
['glpi_rules', 'glpi_ruleactions'], [
|
|
'glpi_ruleactions.rules_id' => new \QueryExpression(DB::quoteName('glpi_rules.id')),
|
|
'glpi_rules.sub_type' => $types,
|
|
'glpi_ruleactions.field' => 'entities_id',
|
|
'glpi_ruleactions.value' => $item->getID()
|
|
]);
|
|
}
|
|
}
|
|
return self::createTabEntry(self::getTypeName(Session::getPluralNumber()), $nb);
|
|
|
|
case 'SLA' :
|
|
case 'OLA' :
|
|
if ($_SESSION['glpishow_count_on_tabs']) {
|
|
$nb = countElementsInTable('glpi_ruleactions',
|
|
['field' => $item::getFieldNames($item->fields['type'])[1],
|
|
'value' => $item->getID()]);
|
|
}
|
|
return self::createTabEntry(self::getTypeName($nb), $nb);
|
|
|
|
default:
|
|
if ($item instanceof Rule) {
|
|
$ong = [];
|
|
$nbcriteria = 0;
|
|
$nbaction = 0;
|
|
if ($_SESSION['glpishow_count_on_tabs']) {
|
|
$nbcriteria = countElementsInTable(getTableForItemType($item->getRuleCriteriaClass()),
|
|
[$item->getRuleIdField() => $item->getID()]);
|
|
$nbaction = countElementsInTable(getTableForItemType($item->getRuleActionClass()),
|
|
[$item->getRuleIdField() => $item->getID()]);
|
|
|
|
}
|
|
|
|
$ong[1] = self::createTabEntry(RuleCriteria::getTypeName(Session::getPluralNumber()),
|
|
$nbcriteria);
|
|
$ong[2] = self::createTabEntry(RuleAction::getTypeName(Session::getPluralNumber()),
|
|
$nbaction);
|
|
return $ong;
|
|
}
|
|
}
|
|
}
|
|
return '';
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $item CommonGLPI object
|
|
* @param $tabnum (default 1)
|
|
* @param $withtemplate (default 0)
|
|
**/
|
|
static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) {
|
|
|
|
if ($item->getType() == 'Entity') {
|
|
$collection = new RuleRightCollection();
|
|
if ($collection->canList()) {
|
|
$ldaprule = new RuleRight();
|
|
$ldaprule->showAndAddRuleForm($item);
|
|
}
|
|
|
|
$collection = new RuleImportEntityCollection();
|
|
if ($collection->canList()) {
|
|
$importrule = new RuleImportEntity();
|
|
$importrule->showAndAddRuleForm($item);
|
|
}
|
|
|
|
$collection = new RuleMailCollectorCollection();
|
|
if ($collection->canList()) {
|
|
$mailcollector = new RuleMailCollector();
|
|
$mailcollector->showAndAddRuleForm($item);
|
|
}
|
|
} else if ($item instanceof LevelAgreement) {
|
|
$item->showRulesList();
|
|
} else if ($item instanceof Rule) {
|
|
$item->getRuleWithCriteriasAndActions($item->getID(), 1, 1);
|
|
switch ($tabnum) {
|
|
case 1 :
|
|
$item->showCriteriasList($item->getID());
|
|
break;
|
|
|
|
case 2 :
|
|
$item->showActionsList($item->getID());
|
|
break;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* Generate unique id for rule based on server name, glpi directory and basetime
|
|
*
|
|
* @since 0.85
|
|
*
|
|
* @return uuid
|
|
**/
|
|
static function getUuid() {
|
|
|
|
//encode uname -a, ex Linux localhost 2.4.21-0.13mdk #1 Fri Mar 14 15:08:06 EST 2003 i686
|
|
$serverSubSha1 = substr(sha1(php_uname('a')), 0, 8);
|
|
// encode script current dir, ex : /var/www/glpi_X
|
|
$dirSubSha1 = substr(sha1(__FILE__), 0, 8);
|
|
|
|
return uniqid("$serverSubSha1-$dirSubSha1-", true);
|
|
}
|
|
|
|
|
|
/**
|
|
* Display debug information for current object
|
|
*
|
|
* @since 0.85
|
|
**/
|
|
function showDebug() {
|
|
|
|
echo "<div class='spaced'>";
|
|
printf(__('%1$s: %2$s'), "<b>UUID</b>", $this->fields['uuid']);
|
|
echo "</div>";
|
|
}
|
|
|
|
public static function canCreate() {
|
|
return static::canUpdate();
|
|
}
|
|
|
|
public static function canPurge() {
|
|
return static::canUpdate();
|
|
}
|
|
|
|
static function getIcon() {
|
|
return "fas fa-book";
|
|
}
|
|
|
|
public function prepareInputForClone($input) {
|
|
//get ranking
|
|
$nextRanking = $this->getNextRanking();
|
|
|
|
//Update fields of the new collection
|
|
$input['name'] = sprintf(__('Copy of %s'), $input['name']);
|
|
$input['is_active'] = 0;
|
|
$input['ranking'] = $nextRanking;
|
|
$input['uuid'] = static::getUuid();
|
|
|
|
$input = Toolbox::addslashes_deep($input);
|
|
|
|
return parent::prepareInputForClone($input);
|
|
}
|
|
}
|