N°985 - Add applicable contexts on Trigger

This commit is contained in:
Eric
2020-01-20 15:50:08 +01:00
parent 2fcea4d02e
commit 900e8ac6d7
21 changed files with 366 additions and 93 deletions

View File

@@ -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');

View File

@@ -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();

View File

@@ -35,6 +35,13 @@
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();
/**
@@ -46,6 +53,11 @@ class ContextTag
static::$aStack[] = $sTag;
}
public static function AddContext($sTag)
{
static::$aStack[] = $sTag;
}
/**
* Cleanup the context stack
*/
@@ -66,10 +78,25 @@ class ContextTag
/**
* 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);
}
}

View File

@@ -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))
{

View File

@@ -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
*/

View File

@@ -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

View File

@@ -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;

View File

@@ -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();

View File

@@ -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();

View File

@@ -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

View File

@@ -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));
}

View File

@@ -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',
));
//

View File

@@ -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',
));
//

View File

@@ -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',

View File

@@ -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',

View File

@@ -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))
{

View File

@@ -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;

View File

@@ -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
View 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());
}
}

View File

@@ -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')
{

View File

@@ -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);