mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01:00
N°985 - Add applicable contexts on Trigger
This commit is contained in:
@@ -51,7 +51,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
{
|
||||
parent::__construct($sTitle, $bPrintable);
|
||||
$this->m_oTabs = new TabManager();
|
||||
$this->oCtx = new ContextTag('GUI:Console');
|
||||
$this->oCtx = new ContextTag(ContextTag::TAG_CONSOLE);
|
||||
|
||||
ApplicationContext::SetUrlMakerClass('iTopStandardURLMaker');
|
||||
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Form\Field\LabelField;
|
||||
use Combodo\iTop\Form\Validator\NotEmptyExtKeyValidator;
|
||||
use Combodo\iTop\Form\Validator\Validator;
|
||||
|
||||
require_once('MyHelpers.class.inc.php');
|
||||
require_once('ormdocument.class.inc.php');
|
||||
require_once('ormstopwatch.class.inc.php');
|
||||
@@ -1022,7 +1026,7 @@ abstract class AttributeDefinition
|
||||
// Validation pattern
|
||||
if ($this->GetValidationPattern() !== '')
|
||||
{
|
||||
$oFormField->AddValidator(new \Combodo\iTop\Form\Validator\Validator($this->GetValidationPattern()));
|
||||
$oFormField->AddValidator(new Validator($this->GetValidationPattern()));
|
||||
}
|
||||
|
||||
// Metadata
|
||||
@@ -6730,7 +6734,7 @@ class AttributeExternalKey extends AttributeDBFieldVoid
|
||||
// If ExtKey is mandatory, we add a validator to ensure that the value 0 is not selected
|
||||
if ($oObject->GetAttributeFlags($this->GetCode()) & OPT_ATT_MANDATORY)
|
||||
{
|
||||
$oFormField->AddValidator(new \Combodo\iTop\Form\Validator\NotEmptyExtKeyValidator());
|
||||
$oFormField->AddValidator(new NotEmptyExtKeyValidator());
|
||||
}
|
||||
|
||||
parent::MakeFormField($oObject, $oFormField);
|
||||
@@ -9812,10 +9816,19 @@ abstract class AttributeSet extends AttributeDBFieldVoid
|
||||
$aValues = array();
|
||||
if (!empty($proposedValue))
|
||||
{
|
||||
foreach(explode(',', $proposedValue) as $sCode)
|
||||
$sSepItem = MetaModel::GetConfig()->Get('tag_set_item_separator');
|
||||
// convert also , separated strings
|
||||
if ($sSepItem !== ',')
|
||||
{
|
||||
$proposedValue = str_replace(',', $sSepItem, $proposedValue);
|
||||
}
|
||||
foreach(explode($sSepItem, $proposedValue) as $sCode)
|
||||
{
|
||||
$sValue = trim($sCode);
|
||||
$aValues[] = $sValue;
|
||||
if ($sValue !== '')
|
||||
{
|
||||
$aValues[] = $sValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aValues;
|
||||
@@ -9835,20 +9848,6 @@ abstract class AttributeSet extends AttributeDBFieldVoid
|
||||
return $this->MakeRealValue($sValue, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $aCols
|
||||
* @param string $sPrefix
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function FromImportToValue($aCols, $sPrefix = '')
|
||||
{
|
||||
$sValue = $aCols["$sPrefix"];
|
||||
|
||||
return $this->MakeRealValue($sValue, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* force an allowed value (type conversion and possibly forces a value as mySQL would do upon writing!
|
||||
*
|
||||
@@ -9951,7 +9950,7 @@ abstract class AttributeSet extends AttributeDBFieldVoid
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -9967,7 +9966,16 @@ abstract class AttributeSet extends AttributeDBFieldVoid
|
||||
}
|
||||
if (is_array($value))
|
||||
{
|
||||
return implode(', ', $value);
|
||||
$sSepItem = MetaModel::GetConfig()->Get('tag_set_item_separator');
|
||||
$sRes = implode($sSepItem, $value);
|
||||
if (!empty($sRes))
|
||||
{
|
||||
$value = "{$sSepItem}{$sRes}{$sSepItem}";
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = '';
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
@@ -9994,6 +10002,43 @@ abstract class AttributeSet extends AttributeDBFieldVoid
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param string $sSeparator
|
||||
* @param string $sTextQualifier
|
||||
* @param \DBObject $oHostObject
|
||||
* @param bool $bLocalize
|
||||
* @param bool $bConvertToPlainText
|
||||
*
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function GetAsCSV($value, $sSeparator = ',', $sTextQualifier = '"', $oHostObject = null, $bLocalize = true, $bConvertToPlainText = false)
|
||||
{
|
||||
$sSepItem = MetaModel::GetConfig()->Get('tag_set_item_separator');
|
||||
if (is_object($value) && ($value instanceof ormSet))
|
||||
{
|
||||
if ($bLocalize)
|
||||
{
|
||||
$aValues = $value->GetLabels();
|
||||
}
|
||||
else
|
||||
{
|
||||
$aValues = $value->GetValues();
|
||||
}
|
||||
$sRes = implode($sSepItem, $aValues);
|
||||
if (!empty($sRes))
|
||||
{
|
||||
$sRes = "{$sSepItem}{$sRes}{$sSepItem}";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sRes = '';
|
||||
}
|
||||
|
||||
return "{$sTextQualifier}{$sRes}{$sTextQualifier}";
|
||||
}
|
||||
|
||||
public function GetMaxItems()
|
||||
{
|
||||
return $this->Get('max_items');
|
||||
@@ -10005,6 +10050,111 @@ abstract class AttributeSet extends AttributeDBFieldVoid
|
||||
}
|
||||
}
|
||||
|
||||
class AttributeEnumSet extends AttributeSet
|
||||
{
|
||||
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_STRING;
|
||||
|
||||
public function GetAllowedValues($aArgs = array(), $sContains = '')
|
||||
{
|
||||
$aRawValues = parent::GetAllowedValues($aArgs, $sContains);
|
||||
if (is_null($aRawValues))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
$aLocalizedValues = array();
|
||||
foreach($aRawValues as $sKey => $sValue)
|
||||
{
|
||||
$aLocalizedValues[$sKey] = $this->GetValueLabel($sKey);
|
||||
}
|
||||
|
||||
return $aLocalizedValues;
|
||||
}
|
||||
|
||||
public function GetValueLabel($sValue)
|
||||
{
|
||||
if (is_null($sValue))
|
||||
{
|
||||
// Unless a specific label is defined for the null value of this enum, use a generic "undefined" label
|
||||
$sLabel = Dict::S('Class:'.$this->GetHostClass().'/Attribute:'.$this->GetCode().'/Value:'.$sValue,
|
||||
Dict::S('Enum:Undefined'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$sLabel = $this->SearchLabel('/Attribute:'.$this->m_sCode.'/Value:'.$sValue, null, true /*user lang*/);
|
||||
if (is_null($sLabel))
|
||||
{
|
||||
$sDefault = str_replace('_', ' ', $sValue);
|
||||
// Browse the hierarchy again, accepting default (english) translations
|
||||
$sLabel = $this->SearchLabel('/Attribute:'.$this->m_sCode.'/Value:'.$sValue, $sDefault, false);
|
||||
}
|
||||
}
|
||||
|
||||
return $sLabel;
|
||||
}
|
||||
|
||||
public function GetValueDescription($sValue)
|
||||
{
|
||||
if (is_null($sValue))
|
||||
{
|
||||
// Unless a specific label is defined for the null value of this enum, use a generic "undefined" label
|
||||
$sDescription = Dict::S('Class:'.$this->GetHostClass().'/Attribute:'.$this->GetCode().'/Value:'.$sValue.'+',
|
||||
Dict::S('Enum:Undefined'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$sDescription = Dict::S('Class:'.$this->GetHostClass().'/Attribute:'.$this->GetCode().'/Value:'.$sValue.'+',
|
||||
'', true /* user language only */);
|
||||
if (strlen($sDescription) == 0)
|
||||
{
|
||||
$sParentClass = MetaModel::GetParentClass($this->m_sHostClass);
|
||||
if ($sParentClass)
|
||||
{
|
||||
if (MetaModel::IsValidAttCode($sParentClass, $this->m_sCode))
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sParentClass, $this->m_sCode);
|
||||
$sDescription = $oAttDef->GetValueDescription($sValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sDescription;
|
||||
}
|
||||
|
||||
public function GetAsHTML($sValue, $oHostObject = null, $bLocalize = true)
|
||||
{
|
||||
if ($bLocalize)
|
||||
{
|
||||
if ($sValue instanceof ormSet)
|
||||
{
|
||||
/** @var ormSet $oOrmSet */
|
||||
$oOrmSet = $sValue;
|
||||
$aRes = array();
|
||||
foreach ($oOrmSet->GetValues() as $sValue)
|
||||
{
|
||||
$sLabel = $this->GetValueLabel($sValue);
|
||||
$sDescription = $this->GetValueDescription($sValue);
|
||||
$aRes[] = "<span title=\"$sDescription\">".parent::GetAsHtml($sLabel)."</span>";
|
||||
}
|
||||
$sRes = implode(', ', $aRes);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sLabel = $this->GetValueLabel($sValue);
|
||||
$sDescription = $this->GetValueDescription($sValue);
|
||||
$sRes = "<span title=\"$sDescription\">".parent::GetAsHtml($sLabel)."</span>";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sRes = parent::GetAsHtml($sValue, $oHostObject, $bLocalize);
|
||||
}
|
||||
|
||||
return $sRes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class AttributeClassAttCodeSet extends AttributeSet
|
||||
{
|
||||
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_STRING;
|
||||
@@ -11018,41 +11168,6 @@ class AttributeTagSet extends AttributeSet
|
||||
return $sRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param string $sSeparator
|
||||
* @param string $sTextQualifier
|
||||
* @param \DBObject $oHostObject
|
||||
* @param bool $bLocalize
|
||||
* @param bool $bConvertToPlainText
|
||||
*
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function GetAsCSV(
|
||||
$value, $sSeparator = ',', $sTextQualifier = '"', $oHostObject = null, $bLocalize = true,
|
||||
$bConvertToPlainText = false
|
||||
) {
|
||||
$sSepItem = MetaModel::GetConfig()->Get('tag_set_item_separator');
|
||||
if (is_object($value) && ($value instanceof ormTagSet))
|
||||
{
|
||||
if ($bLocalize)
|
||||
{
|
||||
$aValues = $value->GetLabels();
|
||||
}
|
||||
else
|
||||
{
|
||||
$aValues = $value->GetValues();
|
||||
}
|
||||
$sRes = implode($sSepItem, $aValues);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sRes = '';
|
||||
}
|
||||
|
||||
return "{$sTextQualifier}{$sRes}{$sTextQualifier}";
|
||||
}
|
||||
|
||||
/**
|
||||
* List the available verbs for 'GetForTemplate'
|
||||
*/
|
||||
@@ -12031,7 +12146,7 @@ class AttributeCustomFields extends AttributeDefinition
|
||||
} catch (Exception $e)
|
||||
{
|
||||
$oForm = new \Combodo\iTop\Form\Form('');
|
||||
$oField = new \Combodo\iTop\Form\Field\LabelField('');
|
||||
$oField = new LabelField('');
|
||||
$oField->SetLabel('Custom field error: '.$e->getMessage());
|
||||
$oForm->AddField($oField);
|
||||
$oForm->Finalize();
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
|
||||
/**
|
||||
* Simple helper class for keeping track of the context inside the call stack
|
||||
*
|
||||
*
|
||||
* To check (anywhere in the code) if a particular context tag is present
|
||||
* in the call stack simply do:
|
||||
*
|
||||
*
|
||||
* if (ContextTag::Check(<the_tag>)) ...
|
||||
*
|
||||
*
|
||||
* For example to know if the code is being executed in the context of a portal do:
|
||||
*
|
||||
*
|
||||
* if (ContextTag::Check('GUI:Portal'))
|
||||
*
|
||||
* @copyright Copyright (C) 2016-2017 Combodo SARL
|
||||
@@ -35,8 +35,15 @@
|
||||
|
||||
class ContextTag
|
||||
{
|
||||
const TAG_PORTAL = 'GUI:Portal';
|
||||
const TAG_CRON = 'CRON';
|
||||
const TAG_CONSOLE = 'GUI:Console';
|
||||
const TAG_SETUP = 'Setup';
|
||||
const TAG_SYNCHRO = 'Synchro';
|
||||
const TAG_REST = 'REST/JSON';
|
||||
|
||||
protected static $aStack = array();
|
||||
|
||||
|
||||
/**
|
||||
* Store a context tag on the stack
|
||||
* @param string $sTag
|
||||
@@ -46,6 +53,11 @@ class ContextTag
|
||||
static::$aStack[] = $sTag;
|
||||
}
|
||||
|
||||
public static function AddContext($sTag)
|
||||
{
|
||||
static::$aStack[] = $sTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup the context stack
|
||||
*/
|
||||
@@ -53,7 +65,7 @@ class ContextTag
|
||||
{
|
||||
array_pop(static::$aStack);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a given tag is present in the stack
|
||||
* @param string $sTag
|
||||
@@ -63,13 +75,28 @@ class ContextTag
|
||||
{
|
||||
return in_array($sTag, static::$aStack);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the whole stack as an array
|
||||
* @return hash
|
||||
* @return array
|
||||
*/
|
||||
public static function GetStack()
|
||||
{
|
||||
return static::$aStack;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the predefined context tags
|
||||
* @return array
|
||||
*/
|
||||
public static function GetTags()
|
||||
{
|
||||
return array(
|
||||
ContextTag::TAG_REST,
|
||||
ContextTag::TAG_SYNCHRO,
|
||||
ContextTag::TAG_SETUP,
|
||||
ContextTag::TAG_CONSOLE,
|
||||
ContextTag::TAG_CRON,
|
||||
ContextTag::TAG_PORTAL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1912,7 +1912,7 @@ abstract class DBObject implements iDisplay
|
||||
|
||||
return "Bad type";
|
||||
}
|
||||
elseif ($oAtt instanceof AttributeClassAttCodeSet)
|
||||
elseif (($oAtt instanceof AttributeClassAttCodeSet) || ($oAtt instanceof AttributeEnumSet))
|
||||
{
|
||||
if (is_string($toCheck))
|
||||
{
|
||||
|
||||
@@ -164,6 +164,17 @@ class ormSet
|
||||
return $aValues;
|
||||
}
|
||||
|
||||
public function GetLabels()
|
||||
{
|
||||
$aLabels = array();
|
||||
$aValues = $this->GetValues();
|
||||
foreach ($aValues as $sValue)
|
||||
{
|
||||
$aLabels[$sValue] = $sValue;
|
||||
}
|
||||
return $aLabels;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array of tag labels indexed by code for only the added tags
|
||||
*/
|
||||
@@ -377,4 +388,4 @@ class ormSet
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,15 +56,49 @@ abstract class Trigger extends cmdbAbstractObject
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("action_list", array("linked_class" => "lnkTriggerAction", "ext_key_to_me" => "trigger_id", "ext_key_to_remote" => "action_id", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => array())));
|
||||
$aTags = ContextTag::GetTags();
|
||||
$sTags = implode(',', $aTags);
|
||||
MetaModel::Init_AddAttribute( new AttributeEnumSet("context", array("allowed_values" => new ValueSetEnum($sTags), "sql" => "context", "depends_on" => array(), "is_null_allowed" => true, "max_items" => 12)));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('finalclass', 'description', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('finalclass', 'description', 'context', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the trigger can be used in the current context
|
||||
*
|
||||
* @return bool true if context OK
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function IsContextValid()
|
||||
{
|
||||
// Check the context
|
||||
$oContext = $this->Get('context');
|
||||
$bChecked = false;
|
||||
$bValid = false;
|
||||
foreach ($oContext->GetValues() as $sValue)
|
||||
{
|
||||
$bChecked = true;
|
||||
if (ContextTag::Check($sValue))
|
||||
{
|
||||
$bValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($bChecked && !$bValid)
|
||||
{
|
||||
// Trigger does not match the current context
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $aContextArgs
|
||||
*
|
||||
@@ -73,6 +107,15 @@ abstract class Trigger extends cmdbAbstractObject
|
||||
*/
|
||||
public function DoActivate($aContextArgs)
|
||||
{
|
||||
// Check the context
|
||||
if (!$this->IsContextValid())
|
||||
{
|
||||
// Trigger does not match the current context
|
||||
IssueLog::Info("Context NOT valid for: ".$this->Get('friendlyname'));
|
||||
return;
|
||||
}
|
||||
IssueLog::Info("Context VALID for: ".$this->Get('friendlyname'));
|
||||
|
||||
// Find the related actions
|
||||
$oLinkedActions = $this->Get('action_list');
|
||||
while ($oLink = $oLinkedActions->Fetch())
|
||||
@@ -133,7 +176,7 @@ abstract class TriggerOnObject extends Trigger
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("filter", array("allowed_values" => null, "sql" => "filter", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('default_search', array('description', 'target_class')); // Default criteria of the search banner
|
||||
@@ -258,7 +301,7 @@ class TriggerOnPortalUpdate extends TriggerOnObject
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
}
|
||||
@@ -292,7 +335,7 @@ abstract class TriggerOnStateChange extends TriggerOnObject
|
||||
MetaModel::Init_AddAttribute(new AttributeClassState("state", array("class_field" => 'target_class', "allowed_values" => null, "sql" => "state", "default_value" => null, "is_null_allowed" => false, "depends_on" => array('target_class'))));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'state')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
|
||||
@@ -326,7 +369,7 @@ class TriggerOnStateEnter extends TriggerOnStateChange
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('target_class', 'state')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
|
||||
@@ -360,7 +403,7 @@ class TriggerOnStateLeave extends TriggerOnStateChange
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('target_class', 'state')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
|
||||
@@ -394,7 +437,7 @@ class TriggerOnObjectCreate extends TriggerOnObject
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
|
||||
@@ -428,7 +471,7 @@ class TriggerOnObjectDelete extends TriggerOnObject
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
|
||||
@@ -464,7 +507,7 @@ class TriggerOnObjectUpdate extends TriggerOnObject
|
||||
MetaModel::Init_AddAttribute(new AttributeClassAttCodeSet('target_attcodes', array("allowed_values" => null, "class_field" => "target_class", "sql" => "target_attcodes", "default_value" => null, "is_null_allowed" => true, "max_items" => 20, "min_items" => 0, "attribute_definition_exclusion_list" => "AttributeDashboard,AttributeExternalField,AttributeFinalClass,AttributeFriendlyName,AttributeObsolescenceDate,AttributeObsolescenceFlag,AttributeSubItem", "attribute_definition_list" => null, "depends_on" => array('target_class'))));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'target_attcodes', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'target_attcodes', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
|
||||
@@ -599,7 +642,7 @@ class TriggerOnThresholdReached extends TriggerOnObject
|
||||
MetaModel::Init_AddAttribute(new AttributeString("threshold_index", array("allowed_values" => null, "sql" => "threshold_index", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'stop_watch_code', 'threshold_index', 'filter', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'stop_watch_code', 'threshold_index', 'filter', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('target_class', 'threshold_index', 'threshold_index')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
|
||||
|
||||
@@ -179,7 +179,7 @@ class UserLocal extends UserInternal
|
||||
|
||||
public function IsPasswordValid()
|
||||
{
|
||||
if (ContextTag::Check('Setup'))
|
||||
if (ContextTag::Check(ContextTag::TAG_SETUP))
|
||||
{
|
||||
// during the setup, the admin account can have whatever password you want ...
|
||||
return true;
|
||||
@@ -190,7 +190,7 @@ class UserLocal extends UserInternal
|
||||
|
||||
public function getPasswordValidityMessage()
|
||||
{
|
||||
if (ContextTag::Check('Setup'))
|
||||
if (ContextTag::Check(ContextTag::TAG_SETUP))
|
||||
{
|
||||
// during the setup, the admin account can have whatever password you want ...
|
||||
return null;
|
||||
|
||||
@@ -23,7 +23,7 @@ require_once(MODULESROOT.'itop-core-update/src/Controller/AjaxController.php');
|
||||
|
||||
MetaModel::LoadConfig(utils::GetConfig());
|
||||
|
||||
new ContextTag('Setup');
|
||||
new ContextTag(ContextTag::TAG_SETUP);
|
||||
|
||||
$oUpdateController = new AjaxController(MODULESROOT.'itop-core-update/view', 'itop-core-update');
|
||||
$oUpdateController->DisableInDemoMode();
|
||||
|
||||
@@ -10,7 +10,7 @@ use Combodo\iTop\CoreUpdate\Controller\UpdateController;
|
||||
use ContextTag;
|
||||
|
||||
require_once(APPROOT.'application/startup.inc.php');
|
||||
new ContextTag('Setup');
|
||||
new ContextTag(ContextTag::TAG_SETUP);
|
||||
|
||||
$oUpdateController = new UpdateController(MODULESROOT.'itop-core-update/view', 'itop-core-update');
|
||||
$oUpdateController->DisableInDemoMode();
|
||||
|
||||
@@ -23,7 +23,7 @@ use Symfony\Component\HttpFoundation\Request;
|
||||
require_once MODULESROOT.'itop-portal-base/portal/config/bootstrap.php';
|
||||
|
||||
// Stacking context tag so it knows we are in the portal
|
||||
$oContext = new ContextTag('GUI:Portal');
|
||||
$oContext = new ContextTag(ContextTag::TAG_PORTAL);
|
||||
$oContext2 = new ContextTag('Portal:' . $_ENV['PORTAL_ID']);
|
||||
|
||||
// Note: Manually refactored ternary condition to be PHP 5.x compatible
|
||||
|
||||
@@ -100,7 +100,7 @@ abstract class AbstractPortalUrlMaker implements iDBObjectURLMaker
|
||||
switch ($sMode)
|
||||
{
|
||||
case 'view':
|
||||
if (!ContextTag::Check('GUI:Portal') || $oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sClass, $iId))
|
||||
if (!ContextTag::Check(ContextTag::TAG_PORTAL) || $oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sClass, $iId))
|
||||
{
|
||||
$sObjectQueryString = $oUrlGenerator->generate('p_object_view', array('sObjectClass' => $sClass, 'sObjectId' => $iId));
|
||||
}
|
||||
@@ -109,11 +109,11 @@ abstract class AbstractPortalUrlMaker implements iDBObjectURLMaker
|
||||
case 'edit':
|
||||
default:
|
||||
// Checking if user is allowed to edit object, if not we check if it can at least view it.
|
||||
if (!ContextTag::Check('GUI:Portal') || $oSecurityHelper->IsActionAllowed(UR_ACTION_MODIFY, $sClass, $iId))
|
||||
if (!ContextTag::Check(ContextTag::TAG_PORTAL) || $oSecurityHelper->IsActionAllowed(UR_ACTION_MODIFY, $sClass, $iId))
|
||||
{
|
||||
$sObjectQueryString = $oUrlGenerator->generate('p_object_edit', array('sObjectClass' => $sClass, 'sObjectId' => $iId));
|
||||
}
|
||||
elseif (!ContextTag::Check('GUI:Portal') || $oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sClass, $iId))
|
||||
elseif (!ContextTag::Check(ContextTag::TAG_PORTAL) || $oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sClass, $iId))
|
||||
{
|
||||
$sObjectQueryString = $oUrlGenerator->generate('p_object_view', array('sObjectClass' => $sClass, 'sObjectId' => $iId));
|
||||
}
|
||||
|
||||
@@ -535,6 +535,18 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'Class:Trigger/Attribute:action_list+' => 'Actions performed when the trigger is activated',
|
||||
'Class:Trigger/Attribute:finalclass' => 'Trigger sub-class',
|
||||
'Class:Trigger/Attribute:finalclass+' => 'Name of the final class',
|
||||
'Class:Trigger/Attribute:context/Value:REST/JSON' => 'REST',
|
||||
'Class:Trigger/Attribute:context/Value:REST/JSON+' => 'REST/JSON',
|
||||
'Class:Trigger/Attribute:context/Value:Synchro' => 'Synchro',
|
||||
'Class:Trigger/Attribute:context/Value:Synchro+' => 'Synchro',
|
||||
'Class:Trigger/Attribute:context/Value:Setup' => 'Setup',
|
||||
'Class:Trigger/Attribute:context/Value:Setup+' => 'Setup',
|
||||
'Class:Trigger/Attribute:context/Value:GUI:Console' => 'Console',
|
||||
'Class:Trigger/Attribute:context/Value:GUI:Console+' => 'GUI:Console',
|
||||
'Class:Trigger/Attribute:context/Value:CRON' => 'CRON',
|
||||
'Class:Trigger/Attribute:context/Value:CRON+' => 'CRON',
|
||||
'Class:Trigger/Attribute:context/Value:GUI:Portal' => 'Portal',
|
||||
'Class:Trigger/Attribute:context/Value:GUI:Portal+' => 'GUI:Portal',
|
||||
));
|
||||
|
||||
//
|
||||
|
||||
@@ -533,6 +533,18 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Class:Trigger/Attribute:action_list+' => '',
|
||||
'Class:Trigger/Attribute:finalclass' => 'Sous-classe de Déclencheur',
|
||||
'Class:Trigger/Attribute:finalclass+' => 'Nom de la classe instanciable',
|
||||
'Class:Trigger/Attribute:context/Value:REST/JSON' => 'REST',
|
||||
'Class:Trigger/Attribute:context/Value:REST/JSON+' => 'REST/JSON',
|
||||
'Class:Trigger/Attribute:context/Value:Synchro' => 'Synchro',
|
||||
'Class:Trigger/Attribute:context/Value:Synchro+' => 'Synchro',
|
||||
'Class:Trigger/Attribute:context/Value:Setup' => 'Setup',
|
||||
'Class:Trigger/Attribute:context/Value:Setup+' => 'Setup',
|
||||
'Class:Trigger/Attribute:context/Value:GUI:Console' => 'Console',
|
||||
'Class:Trigger/Attribute:context/Value:GUI:Console+' => 'GUI:Console',
|
||||
'Class:Trigger/Attribute:context/Value:CRON' => 'CRON',
|
||||
'Class:Trigger/Attribute:context/Value:CRON+' => 'CRON',
|
||||
'Class:Trigger/Attribute:context/Value:GUI:Portal' => 'Portal',
|
||||
'Class:Trigger/Attribute:context/Value:GUI:Portal+' => 'GUI:Portal',
|
||||
));
|
||||
|
||||
//
|
||||
|
||||
@@ -45,6 +45,7 @@ return array(
|
||||
'AttributeEmailAddress' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeEncryptedString' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeEnum' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeEnumSet' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeExternalField' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeExternalKey' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
'AttributeFinalClass' => $baseDir . '/core/attributedef.class.inc.php',
|
||||
|
||||
@@ -275,6 +275,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
||||
'AttributeEmailAddress' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeEncryptedString' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeEnum' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeEnumSet' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeExternalField' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeExternalKey' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
'AttributeFinalClass' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
|
||||
|
||||
@@ -685,7 +685,7 @@ class ApplicationInstaller
|
||||
|
||||
$oProductionEnv = new RunTimeEnvironment($sTargetEnvironment);
|
||||
$oProductionEnv->InitDataModel($oConfig, true); // load data model only
|
||||
$oContextTag = new ContextTag('Setup');
|
||||
$oContextTag = new ContextTag(ContextTag::TAG_SETUP);
|
||||
|
||||
// Migrate columns
|
||||
self::MoveColumns($sDBPrefix);
|
||||
@@ -878,7 +878,7 @@ class ApplicationInstaller
|
||||
|
||||
$oProductionEnv = new RunTimeEnvironment($sTargetEnvironment);
|
||||
$oProductionEnv->InitDataModel($oConfig, true); // load data model and connect to the database
|
||||
$oContextTag = new ContextTag('Setup');
|
||||
$oContextTag = new ContextTag(ContextTag::TAG_SETUP);
|
||||
self::$bMetaModelStarted = true; // No need to reload the final MetaModel in case the installer runs synchronously
|
||||
|
||||
// Perform here additional DB setup... profiles, etc...
|
||||
@@ -945,7 +945,7 @@ class ApplicationInstaller
|
||||
if (!self::$bMetaModelStarted)
|
||||
{
|
||||
$oProductionEnv->InitDataModel($oConfig, false); // load data model and connect to the database
|
||||
$oContextTag = new ContextTag('Setup');
|
||||
$oContextTag = new ContextTag(ContextTag::TAG_SETUP);
|
||||
|
||||
self::$bMetaModelStarted = true; // No need to reload the final MetaModel in case the installer runs synchronously
|
||||
}
|
||||
@@ -1018,7 +1018,7 @@ class ApplicationInstaller
|
||||
// Record which modules are installed...
|
||||
$oProductionEnv = new RunTimeEnvironment($sTargetEnvironment);
|
||||
$oProductionEnv->InitDataModel($oConfig, true); // load data model and connect to the database
|
||||
$oContextTag = new ContextTag('Setup');
|
||||
$oContextTag = new ContextTag(ContextTag::TAG_SETUP);
|
||||
|
||||
if (!$oProductionEnv->RecordInstallation($oConfig, $sDataModelVersion, $aSelectedModuleCodes, $aSelectedExtensionCodes, $sInstallComment))
|
||||
{
|
||||
|
||||
@@ -1528,6 +1528,25 @@ EOF
|
||||
// Exclusion list of AttributeDefinition Classes to filter class_field (empty means no exclusion)
|
||||
$aParameters['attribute_definition_exclusion_list'] = $this->GetPropString($oField, 'attribute_definition_exclusion_list', '');
|
||||
}
|
||||
elseif ($sAttType == 'AttributeEnumSet')
|
||||
{
|
||||
$aTagFieldsInfo[] = $sAttCode;
|
||||
$oValues = $oField->GetUniqueElement('values');
|
||||
$oValueNodes = $oValues->getElementsByTagName('value');
|
||||
$aValues = array();
|
||||
foreach($oValueNodes as $oValue)
|
||||
{
|
||||
// new style... $aValues[] = self::QuoteForPHP($oValue->textContent);
|
||||
$aValues[] = $oValue->textContent;
|
||||
}
|
||||
// new style... $sValues = 'array('.implode(', ', $aValues).')';
|
||||
$sValues = '"'.implode(',', $aValues).'"';
|
||||
$aParameters['allowed_values'] = "new ValueSetEnum($sValues)";
|
||||
$aParameters['sql'] = $this->GetMandatoryPropString($oField, 'sql');
|
||||
$aParameters['is_null_allowed'] = $this->GetPropBoolean($oField, 'is_null_allowed', false);
|
||||
$aParameters['depends_on'] = $sDependencies;
|
||||
$aParameters['max_items'] = $this->GetPropNumber($oField, 'max_items', 12);
|
||||
}
|
||||
elseif ($sAttType == 'AttributeQueryAttCodeSet')
|
||||
{
|
||||
$aTagFieldsInfo[] = $sAttCode;
|
||||
|
||||
@@ -2957,7 +2957,7 @@ class SynchroExecution
|
||||
$this->m_bIsImportPhaseDateKnown = ($oImportPhaseStartDate != null);
|
||||
$this->m_oImportPhaseStartDate = $oImportPhaseStartDate;
|
||||
|
||||
$this->m_oCtx = new ContextTag('Synchro');
|
||||
$this->m_oCtx = new ContextTag(ContextTag::TAG_SYNCHRO);
|
||||
$this->m_oCtx1 = new ContextTag('Synchro:'.$oDataSource->GetRawName()); // More precise context information
|
||||
}
|
||||
|
||||
|
||||
32
test/core/TriggerTest.php
Normal file
32
test/core/TriggerTest.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use ContextTag;
|
||||
use MetaModel;
|
||||
use TriggerOnObjectCreate;
|
||||
|
||||
/**
|
||||
* Class TriggerTest
|
||||
*
|
||||
* @package Combodo\iTop\Test\UnitTest\Core
|
||||
*
|
||||
* @runTestsInSeparateProcesses
|
||||
*/
|
||||
class TriggerTest extends ItopDataTestCase
|
||||
{
|
||||
const USE_TRANSACTION = false;
|
||||
|
||||
public function testIsContextValid()
|
||||
{
|
||||
/** @var TriggerOnObjectCreate $oTrigger */
|
||||
$oTrigger = MetaModel::NewObject('TriggerOnObjectCreate');
|
||||
$oTrigger->Set('context', ContextTag::TAG_PORTAL.', '.ContextTag::TAG_CRON);
|
||||
$this->assertFalse($oTrigger->IsContextValid());
|
||||
ContextTag::AddContext(ContextTag::TAG_SETUP);
|
||||
$this->assertFalse($oTrigger->IsContextValid());
|
||||
ContextTag::AddContext(ContextTag::TAG_CRON);
|
||||
$this->assertTrue($oTrigger->IsContextValid());
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ if (!file_exists($sConfigFile))
|
||||
|
||||
require_once(APPROOT.'/application/startup.inc.php');
|
||||
|
||||
$oCtx = new ContextTag('CRON');
|
||||
$oCtx = new ContextTag(ContextTag::TAG_CRON);
|
||||
|
||||
function ReadMandatoryParam($oP, $sParam, $sSanitizationFilter = 'parameter')
|
||||
{
|
||||
|
||||
@@ -66,7 +66,7 @@ if (!function_exists('json_last_error_msg')) {
|
||||
// Main
|
||||
//
|
||||
$oP = new ajax_page('rest');
|
||||
$oCtx = new ContextTag('REST/JSON');
|
||||
$oCtx = new ContextTag(ContextTag::TAG_REST);
|
||||
|
||||
$sVersion = utils::ReadParam('version', null, false, 'raw_data');
|
||||
$sOperation = utils::ReadParam('operation', null);
|
||||
|
||||
Reference in New Issue
Block a user