diff --git a/addons/userrights/userrightsprofile.class.inc.php b/addons/userrights/userrightsprofile.class.inc.php
index 9039cea2c..0e38717d5 100644
--- a/addons/userrights/userrightsprofile.class.inc.php
+++ b/addons/userrights/userrightsprofile.class.inc.php
@@ -380,7 +380,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
$oContact = new Person();
$oContact->Set('name', 'My last name');
- //$oContact->Set('first_name', 'My first name');
+ $oContact->Set('first_name', 'My first name');
//$oContact->Set('status', 'available');
$oContact->Set('org_id', $iOrgId);
$oContact->Set('email', 'my.email@foo.org');
@@ -421,7 +421,6 @@ class UserRightsProfile extends UserRightsAddOnAPI
{
SetupProfiles::ComputeITILProfiles();
//SetupProfiles::ComputeBasicProfiles();
-
SetupProfiles::DoCreateProfiles();
return true;
}
@@ -562,16 +561,17 @@ exit;
{
// load and cache permissions for the current user on the given class
//
- $aTest = @$this->m_aObjectActionGrants[$oUser->GetKey()][$sClass][$iActionCode];
+ $iUser = $oUser->GetKey();
+ $aTest = @$this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode];
if (is_array($aTest)) return $aTest;
$sAction = self::$m_aActionCodes[$iActionCode];
$iInstancePermission = UR_ALLOWED_NO;
$aAttributes = array();
- if (isset($this->m_aUserProfiles[$oUser->GetKey()]))
+ if (isset($this->m_aUserProfiles[$iUser]))
{
- foreach($this->m_aUserProfiles[$oUser->GetKey()] as $iProfile => $oProfile)
+ foreach($this->m_aUserProfiles[$iUser] as $iProfile => $oProfile)
{
$oGrantRecord = $this->GetProfileActionGrant($iProfile, $sClass, $sAction);
if (is_null($oGrantRecord))
@@ -604,7 +604,7 @@ exit;
'permission' => $iInstancePermission,
'attributes' => $aAttributes,
);
- $this->m_aObjectActionGrants[$oUser->GetKey()][$sClass][$iActionCode] = $aRes;
+ $this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode] = $aRes;
return $aRes;
}
@@ -728,13 +728,14 @@ exit;
public function IsStimulusAllowed($oUser, $sClass, $sStimulusCode, $oInstanceSet = null)
{
// Note: this code is VERY close to the code of IsActionAllowed()
+ $iUser = $oUser->GetKey();
if (is_null($oInstanceSet))
{
$iInstancePermission = UR_ALLOWED_NO;
- if (isset($this->m_aUserProfiles[$oUser->GetKey()]))
+ if (isset($this->m_aUserProfiles[$iUser]))
{
- foreach($this->m_aUserProfiles[$oUser->GetKey()] as $iProfile => $oProfile)
+ foreach($this->m_aUserProfiles[$iUser] as $iProfile => $oProfile)
{
$oGrantRecord = $this->GetClassStimulusGrant($iProfile, $sClass, $sStimulusCode);
if (!is_null($oGrantRecord))
@@ -751,9 +752,9 @@ exit;
while($oObject = $oInstanceSet->Fetch())
{
$iInstancePermission = UR_ALLOWED_NO;
- if (isset($this->m_aUserProfiles[$oUser->GetKey()]))
+ if (isset($this->m_aUserProfiles[$iUser]))
{
- foreach($this->m_aUserProfiles[$oUser->GetKey()] as $iProfile => $oProfile)
+ foreach($this->m_aUserProfiles[$iUser] as $iProfile => $oProfile)
{
$oGrantRecord = $this->GetClassStimulusGrant($iProfile, get_class($oObject), $sStimulusCode);
if (!is_null($oGrantRecord))
diff --git a/addons/userrights/userrightsprojection.class.inc.php b/addons/userrights/userrightsprojection.class.inc.php
index 077d451af..dc4aab1f2 100644
--- a/addons/userrights/userrightsprojection.class.inc.php
+++ b/addons/userrights/userrightsprojection.class.inc.php
@@ -616,7 +616,7 @@ class UserRightsProjection extends UserRightsAddOnAPI
$oContact = new Person();
$oContact->Set('name', 'My last name');
- //$oContact->Set('first_name', 'My first name');
+ $oContact->Set('first_name', 'My first name');
//$oContact->Set('status', 'available');
$oContact->Set('org_id', $iOrgId);
$oContact->Set('email', 'my.email@foo.org');
diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php
index d4c14dd5d..d541eeef6 100644
--- a/core/attributedef.class.inc.php
+++ b/core/attributedef.class.inc.php
@@ -160,7 +160,6 @@ abstract class AttributeDefinition
public function IsExternalField() {return false;}
public function IsWritable() {return false;}
public function IsNullAllowed() {return true;}
- public function GetNullValue() {return null;}
public function GetCode() {return $this->m_sCode;}
public function GetLabel() {return Dict::S('Class:'.$this->m_sHostClass.'/Attribute:'.$this->m_sCode, $this->m_sCode);}
public function GetLabel_Obsolete()
@@ -192,6 +191,9 @@ abstract class AttributeDefinition
public function GetValuesDef() {return null;}
public function GetPrerequisiteAttributes() {return array();}
+ public function GetNullValue() {return null;}
+ public function IsNull($proposedValue) {return is_null($proposedValue);}
+
public function MakeRealValue($proposedValue) {return $proposedValue;} // force an allowed value (type conversion and possibly forces a value as mySQL would do upon writing!)
public function GetSQLExpressions() {return array();} // returns suffix/expression pairs (1 in most of the cases), for READING (Select)
@@ -205,7 +207,7 @@ abstract class AttributeDefinition
return '';
}
- public function CheckValue($value)
+ public function CheckFormat($value)
{
return true;
}
@@ -544,12 +546,22 @@ class AttributeInteger extends AttributeDBField
}
}
+ public function GetNullValue()
+ {
+ return null;
+ }
+ public function IsNull($proposedValue)
+ {
+ return is_null($proposedValue);
+ }
+
public function MakeRealValue($proposedValue)
{
- //return intval($proposedValue); could work as well
+ if (is_null($proposedValue)) return null;
if ($proposedValue == '') return null;
return (int)$proposedValue;
}
+
public function ScalarToSQL($value)
{
assert(is_numeric($value) || is_null($value));
@@ -577,9 +589,12 @@ class AttributeBoolean extends AttributeInteger
public function MakeRealValue($proposedValue)
{
+ if (is_null($proposedValue)) return null;
+ if ($proposedValue == '') return null;
if ((int)$proposedValue) return true;
return false;
}
+
public function ScalarToSQL($value)
{
assert(is_bool($value));
@@ -606,7 +621,7 @@ class AttributeString extends AttributeDBField
public function GetEditClass() {return "String";}
protected function GetSQLCol() {return "VARCHAR(255)";}
- public function CheckValue($value)
+ public function CheckFormat($value)
{
$sRegExp = $this->GetValidationPattern();
if (empty($sRegExp))
@@ -659,15 +674,22 @@ class AttributeString extends AttributeDBField
}
}
+ public function GetNullValue()
+ {
+ return '';
+ }
+
+ public function IsNull($proposedValue)
+ {
+ return ($proposedValue == '');
+ }
+
public function MakeRealValue($proposedValue)
{
- if (is_null($proposedValue)) return null;
+ if (is_null($proposedValue)) return '';
return (string)$proposedValue;
- // if (!settype($proposedValue, "string"))
- // {
- // throw new CoreException("Failed to change the type of '$proposedValue' to a string");
- // }
}
+
public function ScalarToSQL($value)
{
if (!is_string($value) && !is_null($value))
@@ -1029,14 +1051,6 @@ class AttributeEnum extends AttributeString
}
return $aLocalizedValues;
}
-
- public function MakeRealValue($proposedValue)
- {
- // For an enum, let's consider an empty value like a null value
- // Could be implemented by changing the UI : no value => let the default value
- if ($proposedValue == '') return null;
- return parent::MakeRealValue($proposedValue);
- }
}
/**
@@ -1420,7 +1434,6 @@ class AttributeExternalKey extends AttributeDBFieldVoid
public function GetDefaultValue() {return 0;}
public function IsNullAllowed() {return $this->Get("is_null_allowed");}
- public function GetNullValue() {return 0;}
public function GetBasicFilterOperators()
{
@@ -1468,8 +1481,20 @@ class AttributeExternalKey extends AttributeDBFieldVoid
return $this->Get("on_target_delete");
}
+ public function GetNullValue()
+ {
+ return 0;
+ }
+
+ public function IsNull($proposedValue)
+ {
+ return ($proposedValue == 0);
+ }
+
public function MakeRealValue($proposedValue)
{
+ if (is_null($proposedValue)) return 0;
+ if (MetaModel::IsValidObject($proposedValue)) return $proposedValue->GetKey();
return (int)$proposedValue;
}
}
@@ -1619,11 +1644,24 @@ class AttributeExternalField extends AttributeDefinition
return $oExtAttDef->GetBasicFilterSQLExpr($sOpCode, $value);
}
+ public function GetNullValue()
+ {
+ $oExtAttDef = $this->GetExtAttDef();
+ return $oExtAttDef->GetNullValue();
+ }
+
+ public function IsNull($proposedValue)
+ {
+ $oExtAttDef = $this->GetExtAttDef();
+ return $oExtAttDef->IsNull($proposedValue);
+ }
+
public function MakeRealValue($proposedValue)
{
$oExtAttDef = $this->GetExtAttDef();
return $oExtAttDef->MakeRealValue($proposedValue);
}
+
public function ScalarToSQL($value)
{
// This one could be used in case of filtering only
diff --git a/core/bulkchange.class.inc.php b/core/bulkchange.class.inc.php
index 16b0cb18f..7abffa53a 100644
--- a/core/bulkchange.class.inc.php
+++ b/core/bulkchange.class.inc.php
@@ -320,13 +320,15 @@ class BulkChange
// skip the private key, if any
if ($sAttCode == 'id') continue;
- if (!$oTargetObj->CheckValue($sAttCode, $aRowData[$iCol]))
+ $res = $oTargetObj->CheckValue($sAttCode, $aRowData[$iCol]);
+ if ($res === true)
{
- $aErrors[$sAttCode] = "Unexpected value";
+ $oTargetObj->Set($sAttCode, $aRowData[$iCol]);
}
else
{
- $oTargetObj->Set($sAttCode, $aRowData[$iCol]);
+ // $res is a string with the error description
+ $aErrors[$sAttCode] = "Unexpected value for attribute '$sAttCode': $res";
}
}
@@ -363,9 +365,11 @@ class BulkChange
// Checks
//
- if (!$oTargetObj->CheckConsistency())
+ $res = $oTargetObj->CheckConsistency();
+ if ($res !== true)
{
- $aErrors["GLOBAL"] = "Attributes not consistent with each others";
+ // $res contains the error description
+ $aErrors["GLOBAL"] = "Attributes not consistent with each others: $res";
}
return $aResults;
}
diff --git a/core/coreexception.class.inc.php b/core/coreexception.class.inc.php
index da1094b81..b11da9003 100644
--- a/core/coreexception.class.inc.php
+++ b/core/coreexception.class.inc.php
@@ -107,4 +107,8 @@ class CoreWarning extends CoreException
{
}
+class CoreUnexpectedValue extends CoreException
+{
+}
+
?>
diff --git a/core/dbobject.class.php b/core/dbobject.class.php
index 751ec3987..add8bed3a 100644
--- a/core/dbobject.class.php
+++ b/core/dbobject.class.php
@@ -41,6 +41,9 @@ abstract class DBObject
private $m_bDirty = false; // Means: "a modification is ongoing"
// The object may have incorrect external keys, then any attempt of reload must be avoided
+ private $m_bCheckStatus = null; // Means: the object has been verified and is consistent with integrity rules
+ // if null, then the check has to be performed again to know the status
+ // otherwise,
private $m_bFullyLoaded = false; // Compound objects can be partially loaded
private $m_aLoadedAtt = array(); // Compound objects can be partially loaded, array of sAttCode
@@ -194,6 +197,7 @@ abstract class DBObject
$this->m_aCurrValues = array();
$this->m_aOrigValues = array();
$this->m_aLoadedAtt = array();
+ $this->m_bCheckStatus = true;
// Get the key
//
@@ -251,13 +255,8 @@ abstract class DBObject
if ($sAttCode == 'finalclass')
{
// Ignore it - this attribute is set upon object creation and that's it
- //throw new CoreWarning('Attempting to set the value for the internal attribute \"finalclass\"', array('current value'=>$this->Get('finalclass'), 'new value'=>$value));
return;
}
- if (!array_key_exists($sAttCode, MetaModel::ListAttributeDefs(get_class($this))))
- {
- throw new CoreException("Unknown attribute code '$sAttCode' for the class ".get_class($this));
- }
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
if ($this->m_bIsInDB && !$this->m_bFullyLoaded && !$this->m_bDirty)
{
@@ -266,12 +265,7 @@ abstract class DBObject
// + consistency does not make sense !
$this->Reload();
}
- if($oAttDef->IsScalar() && !$oAttDef->IsNullAllowed() && is_null($value))
- {
- throw new CoreWarning("null not allowed for attribute '$sAttCode', setting default value");
- $this->m_aCurrValues[$sAttCode] = $oAttDef->GetDefaultValue();
- return;
- }
+
if ($oAttDef->IsExternalKey() && is_object($value))
{
// Setting an external key with a whole object (instead of just an ID)
@@ -279,11 +273,11 @@ abstract class DBObject
// (useful when building objects in memory and not from a query)
if ( (get_class($value) != $oAttDef->GetTargetClass()) && (!is_subclass_of($value, $oAttDef->GetTargetClass())))
{
- throw new CoreWarning("Trying to set the value of '$sAttCode', to an object of class '".get_class($value)."', whereas it's an ExtKey to '".$oAttDef->GetTargetClass()."'. Ignored");
- $this->m_aCurrValues[$sAttCode] = $oAttDef->GetDefaultValue();
+ throw new CoreUnexpectedValue("Trying to set the value of '$sAttCode', to an object of class '".get_class($value)."', whereas it's an ExtKey to '".$oAttDef->GetTargetClass()."'. Ignored");
}
else
{
+ $this->m_bCheckStatus = null;
$this->m_aCurrValues[$sAttCode] = $value->GetKey();
foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sCode => $oDef)
{
@@ -297,17 +291,13 @@ abstract class DBObject
}
if(!$oAttDef->IsScalar() && !is_object($value))
{
- throw new CoreWarning("scalar not allowed for attribute '$sAttCode', setting default value (empty list)");
- $this->m_aCurrValues[$sAttCode] = $oAttDef->GetDefaultValue();
- return;
+ throw new CoreUnexpectedValue("scalar not allowed for attribute '$sAttCode', setting default value (empty list)");
}
if($oAttDef->IsLinkSet())
{
if((get_class($value) != 'DBObjectSet') && !is_subclass_of($value, 'DBObjectSet'))
{
- throw new CoreWarning("expecting a set of persistent objects (found a '".get_class($value)."'), setting default value (empty list)");
- $this->m_aCurrValues[$sAttCode] = $oAttDef->GetDefaultValue();
- return;
+ throw new CoreUnexpectedValue("expecting a set of persistent objects (found a '".get_class($value)."'), setting default value (empty list)");
}
$oObjectSet = $value;
@@ -316,18 +306,17 @@ abstract class DBObject
// not working fine :-( if (!is_subclass_of($sSetClass, $sLinkClass))
if ($sSetClass != $sLinkClass)
{
- throw new CoreWarning("expecting a set of '$sLinkClass' objects (found a set of '$sSetClass'), setting default value (empty list)");
- $this->m_aCurrValues[$sAttCode] = $oAttDef->GetDefaultValue();
- return;
+ throw new CoreUnexpectedValue("expecting a set of '$sLinkClass' objects (found a set of '$sSetClass'), setting default value (empty list)");
}
}
- if ($oAttDef->CheckValue($value))
- {
- $this->m_aCurrValues[$sAttCode] = $oAttDef->MakeRealValue($value);
- $this->RegisterAsDirty(); // Make sure we do not reload it anymore... before saving it
- }
+
+ $realvalue = $oAttDef->MakeRealValue($value);
+ $this->m_aCurrValues[$sAttCode] = $realvalue;
+
+ $this->m_bCheckStatus = null;
+ $this->RegisterAsDirty(); // Make sure we do not reload it anymore... before saving it
}
-
+
public function Get($sAttCode)
{
if (!array_key_exists($sAttCode, MetaModel::ListAttributeDefs(get_class($this))))
@@ -599,6 +588,8 @@ abstract class DBObject
}
// check if the given (or current) value is suitable for the attribute
+ // return true if successfull
+ // return the error desciption otherwise
public function CheckValue($sAttCode, $value = null)
{
if (!is_null($value))
@@ -611,44 +602,46 @@ abstract class DBObject
}
$oAtt = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
- if ($oAtt->IsExternalKey())
+ if (!$oAtt->IsWritable())
{
- if (!$oAtt->IsNullAllowed() || ($toCheck != 0) )
+ return true;
+ }
+ elseif ($oAtt->IsNull($toCheck))
+ {
+ if ($oAtt->IsNullAllowed())
{
- try
- {
- $oTargetObj = MetaModel::GetObject($oAtt->GetTargetClass(), $toCheck);
- return true;
- }
- catch (CoreException $e)
- {
- return false;
- }
+ return true;
+ }
+ else
+ {
+ return "Null not allowed";
}
}
- elseif ($oAtt->IsWritable() && $oAtt->IsScalar())
+ elseif ($oAtt->IsExternalKey())
{
- if (is_null($toCheck))
+ $sTargetClass = $oAtt->GetTargetClass();
+ $oTargetObj = MetaModel::GetObject($sTargetClass, $toCheck, false /*must be found*/, true /*allow all data*/);
+ if (is_null($oTargetObj))
{
- if ($oAtt->IsNullAllowed())
- {
- return true;
- }
- else
- {
- return false;
- }
+ return "Target object not found ($sTargetClass::$toCheck)";
}
- $aValues = $oAtt->GetAllowedValues();
+ }
+ elseif ($oAtt->IsScalar())
+ {
+ $aValues = $oAtt->GetAllowedValues($this->ToArgs());
if (count($aValues) > 0)
{
if (!array_key_exists($toCheck, $aValues))
{
- return false;
+ return "Value not allowed [$toCheck]";
}
}
+ elseif (!$oAtt->CheckFormat($toCheck))
+ {
+ return "Wrong format [$toCheck]";
+ }
}
- return $oAtt->CheckValue($toCheck); // Check the format
+ return true;
}
// check attributes together
@@ -657,45 +650,57 @@ abstract class DBObject
return true;
}
- // check if it is allowed to record the new object into the database
+ // check integrity rules (before inserting or updating the object)
// a displayable error is returned
- // Note: checks the values and consistency
- public function CheckToInsert()
+ public function DoCheckToWrite()
{
- $aIssues = array();
+ $this->m_aCheckIssues = array();
+
foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sAttCode=>$oAttDef)
{
- if (!$this->CheckValue($sAttCode))
+ $res = $this->CheckValue($sAttCode);
+ if ($res !== true)
{
- $aIssues[$sAttCode] = array(
- 'issue' => 'unexpected value'
- );
+ // $res contains the error description
+ $this->m_aCheckIssues[] = "Unexpected value for attribute '$sAttCode': $res";
}
}
- if (count($aIssues) > 0)
+ if (count($this->m_aCheckIssues) > 0)
{
- return array(false, $aIssues);
+ // No need to check consistency between attributes if any of them has
+ // an unexpected value
+ return;
}
- if (!$this->CheckConsistency())
+ $res = $this->CheckConsistency();
+ if ($res !== true)
{
- return array(false, $aIssues);
+ // $res contains the error description
+ $this->m_aCheckIssues[] = "Consistency rules not followed: $res";
}
- return array(true, $aIssues);
}
- // check if it is allowed to update the existing object into the database
- // a displayable error is returned
- // Note: checks the values and consistency
- public function CheckToUpdate()
+ final public function CheckToWrite()
{
- foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sAttCode=>$oAttDef)
+ if (false)
{
- if (!$this->CheckValue($sAttCode)) return false;
+ return array(true, array());
}
- if (!$this->CheckConsistency()) return false;
- return true;
+
+ if (is_null($this->m_bCheckStatus))
+ {
+ $this->DoCheckToWrite();
+ if (count($this->m_aCheckIssues) == 0)
+ {
+ $this->m_bCheckStatus = true;
+ }
+ else
+ {
+ $this->m_bCheckStatus = false;
+ }
+ }
+ return array($this->m_bCheckStatus, $this->m_aCheckIssues);
}
-
+
// check if it is allowed to delete the existing object from the database
// a displayable error is returned
public function CheckToDelete()
@@ -863,10 +868,17 @@ abstract class DBObject
{
if (empty($this->m_iKey))
{
- throw new CoreWarning("Missing key for the object to write - This class is supposed to have a user defined key, not an autonumber");
+ throw new CoreWarning("Missing key for the object to write - This class is supposed to have a user defined key, not an autonumber", array('class' => $sRootClass));
}
}
+ // Ultimate check - ensure DB integrity
+ list($bRes, $aIssues) = $this->CheckToWrite();
+ if (!$bRes)
+ {
+ throw new CoreException("Object not following integrity rules - it will not be written into the DB", array('class' => $sClass, 'id' => $this->GetKey(), 'issues' => $aIssues));
+ }
+
// First query built upon on the root class, because the ID must be created first
$this->m_iKey = $this->DBInsertSingleTable($sRootClass);
@@ -951,6 +963,14 @@ abstract class DBObject
//throw new CoreWarning("Attempting to update an unchanged object");
return;
}
+
+ // Ultimate check - ensure DB integrity
+ list($bRes, $aIssues) = $this->CheckToWrite();
+ if (!$bRes)
+ {
+ throw new CoreException("Object not following integrity rules - it will not be written into the DB", array('class' => get_class($this), 'id' => $this->GetKey(), 'issues' => $aIssues));
+ }
+
$bHasANewExternalKeyValue = false;
foreach($aChanges as $sAttCode => $valuecurr)
{
diff --git a/core/metamodel.class.php b/core/metamodel.class.php
index 83c1b01ae..b18a23dba 100644
--- a/core/metamodel.class.php
+++ b/core/metamodel.class.php
@@ -3257,7 +3257,7 @@ abstract class MetaModel
return $iTotalHits.' ('.implode(', ', $aRes).')';
}
- public static function MakeSingleRow($sClass, $iKey, $bMustBeFound = true)
+ public static function MakeSingleRow($sClass, $iKey, $bMustBeFound = true, $bAllowAllData = false)
{
if (!array_key_exists($sClass, self::$aQueryCacheGetObject))
{
@@ -3268,6 +3268,10 @@ abstract class MetaModel
// or a view... next optimization to come!
$oFilter = new DBObjectSearch($sClass);
$oFilter->AddCondition('id', 987654321, '=');
+ if ($bAllowAllData)
+ {
+ $oFilter->AllowAllData();
+ }
$sSQL = self::MakeSelectQuery($oFilter);
self::$aQueryCacheGetObject[$sClass] = $sSQL;
@@ -3323,10 +3327,10 @@ abstract class MetaModel
return new $sClass($aRow, $sClassAlias);
}
- public static function GetObject($sClass, $iKey, $bMustBeFound = true)
+ public static function GetObject($sClass, $iKey, $bMustBeFound = true, $bAllowAllData = false)
{
self::_check_subclass($sClass);
- $aRow = self::MakeSingleRow($sClass, $iKey, $bMustBeFound);
+ $aRow = self::MakeSingleRow($sClass, $iKey, $bMustBeFound, $bAllowAllData);
if (empty($aRow))
{
return null;
diff --git a/core/test.class.inc.php b/core/test.class.inc.php
index dd45d16e5..30949936c 100644
--- a/core/test.class.inc.php
+++ b/core/test.class.inc.php
@@ -395,10 +395,10 @@ abstract class TestBizModel extends TestHandler
protected $m_oChange;
protected function ObjectToDB($oNew, $bReload = false)
{
- list($bRes, $aIssues) = $oNew->CheckToInsert();
+ list($bRes, $aIssues) = $oNew->CheckToWrite();
if (!$bRes)
{
- throw new CoreException('Could not create object, unexpected values', array('attributes' => $aIssues));
+ throw new CoreException('Could not create object, unexpected values', array('issues' => $aIssues));
}
if ($oNew instanceof CMDBObject)
{
diff --git a/core/userrights.class.inc.php b/core/userrights.class.inc.php
index bd4e91e72..e4efc8467 100644
--- a/core/userrights.class.inc.php
+++ b/core/userrights.class.inc.php
@@ -498,8 +498,8 @@ class UserRights
// Need to load some records before the login is performed (user preferences)
if (MetaModel::HasCategory($sClass, 'alwaysreadable')) return true;
- // ne marche pas... pourquoi?
- //if (!self::CheckLogin()) return false;
+ // When initializing, we need to let everything pass trough
+ if (!self::CheckLogin()) return true;
if (self::IsAdministrator()) return true;
@@ -514,7 +514,9 @@ class UserRights
public static function IsActionAllowed($sClass, $iActionCode, /*dbObjectSet*/ $oInstanceSet = null, $oUser = null)
{
- if (!self::CheckLogin()) return false;
+ // When initializing, we need to let everything pass trough
+ if (!self::CheckLogin()) return true;
+
if (self::IsAdministrator($oUser)) return true;
@@ -537,7 +539,9 @@ class UserRights
public static function IsStimulusAllowed($sClass, $sStimulusCode, /*dbObjectSet*/ $oInstanceSet = null, $oUser = null)
{
- if (!self::CheckLogin()) return false;
+ // When initializing, we need to let everything pass trough
+ if (!self::CheckLogin()) return true;
+
if (self::IsAdministrator($oUser)) return true;
// this module is forbidden for non admins
@@ -555,8 +559,8 @@ class UserRights
public static function IsActionAllowedOnAttribute($sClass, $sAttCode, $iActionCode, /*dbObjectSet*/ $oInstanceSet = null, $oUser = null)
{
- if (!self::CheckLogin()) return false;
- if (self::IsAdministrator($oUser)) return true;
+ // When initializing, we need to let everything pass trough
+ if (!self::CheckLogin()) return true;
// this module is forbidden for non admins
if (MetaModel::HasCategory($sClass, 'addon/userrights')) return false;
diff --git a/dictionaries/dictionary.itop.ui.php b/dictionaries/dictionary.itop.ui.php
index b71d888e4..eddc4b8d4 100644
--- a/dictionaries/dictionary.itop.ui.php
+++ b/dictionaries/dictionary.itop.ui.php
@@ -159,6 +159,25 @@ Dict::Add('EN US', 'English', 'English', array(
'Class:URP_UserProfile/Attribute:reason+' => 'explain why this person may have this role',
));
+//
+// Class: URP_UserOrg
+//
+
+Dict::Add('EN US', 'English', 'English', array(
+ 'Class:URP_UserOrg' => 'User organizations',
+ 'Class:URP_UserOrg+' => 'Allowed organizations',
+ 'Class:URP_UserProfile/Attribute:userid' => 'User',
+ 'Class:URP_UserProfile/Attribute:userid+' => 'user account',
+ 'Class:URP_UserProfile/Attribute:userlogin' => 'Login',
+ 'Class:URP_UserProfile/Attribute:userlogin+' => 'User\'s login',
+ 'Class:URP_UserProfile/Attribute:allowed_org_id' => 'Organization',
+ 'Class:URP_UserProfile/Attribute:allowed_org_id+' => 'Allowed organization',
+ 'Class:URP_UserProfile/Attribute:allowed_org_name' => 'Organization',
+ 'Class:URP_UserProfile/Attribute:allowed_org_name+' => 'Allowed organization',
+ 'Class:URP_UserProfile/Attribute:reason' => 'Reason',
+ 'Class:URP_UserProfile/Attribute:reason+' => 'explain why this person is allowed to see the data belonging to this organization',
+));
+
//
// Class: URP_ProfileProjection
//
diff --git a/dictionaries/fr.dictionary.itop.ui.php b/dictionaries/fr.dictionary.itop.ui.php
index 4d90e1a2c..c102072e8 100644
--- a/dictionaries/fr.dictionary.itop.ui.php
+++ b/dictionaries/fr.dictionary.itop.ui.php
@@ -156,7 +156,26 @@ Dict::Add('FR FR', 'French', 'Français', array(
'Class:URP_UserProfile/Attribute:profile' => 'Profil',
'Class:URP_UserProfile/Attribute:profile+' => '',
'Class:URP_UserProfile/Attribute:reason' => 'Raison',
- 'Class:URP_UserProfile/Attribute:reason+' => 'Justifie le rôles affecté à cet utilisateur',
+ 'Class:URP_UserProfile/Attribute:reason+' => 'Justifie le rôle affecté à cet utilisateur',
+));
+
+//
+// Class: URP_UserOrg
+//
+
+Dict::Add('EN US', 'English', 'English', array(
+ 'Class:URP_UserOrg' => 'Utilisateur/Organisation',
+ 'Class:URP_UserOrg+' => 'Organizations permises pour l\'utilisateur',
+ 'Class:URP_UserProfile/Attribute:userid' => 'Utilisateur',
+ 'Class:URP_UserProfile/Attribute:userid+' => '',
+ 'Class:URP_UserProfile/Attribute:userlogin' => 'Login',
+ 'Class:URP_UserProfile/Attribute:userlogin+' => '',
+ 'Class:URP_UserProfile/Attribute:allowed_org_id' => 'Organisation',
+ 'Class:URP_UserProfile/Attribute:allowed_org_id+' => '',
+ 'Class:URP_UserProfile/Attribute:allowed_org_name' => 'Organisation',
+ 'Class:URP_UserProfile/Attribute:allowed_org_name+' => '',
+ 'Class:URP_UserProfile/Attribute:reason' => 'Raison',
+ 'Class:URP_UserProfile/Attribute:reason+' => 'Justifie la permission de voir les données de cette organisation',
));
//
diff --git a/pages/UI.php b/pages/UI.php
index aa6e7b739..a246d632e 100644
--- a/pages/UI.php
+++ b/pages/UI.php
@@ -874,7 +874,7 @@ try
{
$oP->p(Dict::Format('UI:Class_Object_NotUpdated', MetaModel::GetName(get_class($oObj)), $oObj->GetName()));
}
- else if ($oObj->CheckToUpdate())
+ else
{
$oMyChange = MetaModel::NewObject("CMDBChange");
$oMyChange->Set("date", time());
@@ -892,10 +892,6 @@ try
$oP->p(Dict::Format('UI:Class_Object_Updated', MetaModel::GetName(get_class($oObj)), $oObj->GetName()));
}
- else
- {
- $oP->p("".Dict::S('UI:Error:ObjectCannotBeUpdated')."\n");
- }
}
else
{
@@ -1215,7 +1211,7 @@ EOF
$oObj->Set($sAttCode, $paramValue);
}
}
- if ($oObj->ApplyStimulus($sStimulus) && $oObj->CheckToUpdate())
+ if ($oObj->ApplyStimulus($sStimulus))
{
$oMyChange = MetaModel::NewObject("CMDBChange");
$oMyChange->Set("date", time());
diff --git a/pages/run_query.php b/pages/run_query.php
index d1ef26029..c1ed44f70 100644
--- a/pages/run_query.php
+++ b/pages/run_query.php
@@ -112,7 +112,6 @@ try
echo "FYI: '$sClearText'
\n";
$oFilter = DBObjectSearch::unserialize($sExpression);
$sExpression = $oFilter->ToOQL();
- exit;
}
else
{
diff --git a/setup/index.php b/setup/index.php
index 84904cfc0..e1dd3122c 100644
--- a/setup/index.php
+++ b/setup/index.php
@@ -411,6 +411,12 @@ function CreateAdminAccount(SetupWebPage $oP, Config $oConfig, $sAdminUser, $sAd
{
$oP->log('Info - CreateAdminAccount');
InitDataModel($oP, TMP_CONFIG_FILE, false); // load data model and connect to the database
+
+ if (!UserRights::Setup())
+ {
+ return false;
+ }
+
if (UserRights::CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage))
{
$oP->ok("Administrator account '$sAdminUser' created.");
@@ -908,7 +914,7 @@ function SampleDataSelection(SetupWebPage $oP, $aParamValues, $iCurrentStep, Con
$oP->add("\n");
AddParamsToForm($oP, $aParamValues, array('sample_data'));
- if (CreateAdminAccount($oP, $oConfig, $sAdminUser, $sAdminPwd, $sLanguage) && UserRights::Setup())
+ if (CreateAdminAccount($oP, $oConfig, $sAdminUser, $sAdminPwd, $sLanguage))
{
$oP->add("