Compare commits

..

4 Commits

Author SHA1 Message Date
xavier.guiboud-ribaud@combodo.com
8103f4c92c 7746 - Caselog edition button active even if the user has a read-only access to the object
Remove unwanted modifications pushed on the wrong branch
2024-11-26 13:54:19 +01:00
xavier.guiboud-ribaud@combodo.com
d6f3ee9758 7746 - Caselog edition button active even if the user has a read-only access to the object
Coding conventions compliance
2024-11-26 10:17:52 +01:00
xavier.guiboud-ribaud@combodo.com
808168b9e7 N°7984 - Change ? for field description (tooltip) by 🛈 in console and portal 2024-11-26 08:05:52 +01:00
xavier.guiboud-ribaud@combodo.com
120eb702a7 7746 - Caselog edition button active even if the user has a read-only access to the object 2024-11-25 16:01:39 +01:00
1473 changed files with 95733 additions and 149467 deletions

View File

@@ -93,12 +93,6 @@ gitGraph
checkout support/3.2
commit id: "2024-06-25" tag: "3.2.0-beta1" type: REVERSE
commit id: "2024-08-07" tag: "3.2.0"
checkout support/2.7
commit id: "2025-02-25" tag: "2.7.12"
checkout support/3.1
commit id: "2025-02-25 " tag: "3.1.3"
checkout support/3.2
commit id: "2025-02-25 " tag: "3.2.1"
```
To learn more, check the [iTop community versions history on the official wiki](https://www.itophub.io/wiki/page?id=latest:release:start).

2
.gitignore vendored
View File

@@ -33,7 +33,7 @@ tests/*/vendor/*
!/data/index.php
!/data/web.config
!/data/exclude.txt
!/data/.compilation-symlinks
# iTop extensions
/extensions/**

View File

@@ -25,7 +25,7 @@ if (false === file_exists($sTcPdfRootFolder)) {
echo $sCurrentScriptFileName.": No TCPDF lib detected, exiting !\n";
return;
}
$sTcPdfFontsFolder = $sTcPdfRootFolder.'/fonts/';
$sTcPdfFontsFolder = $sTcPdfRootFolder.'/Fonts/';
/**

View File

@@ -1,9 +1,5 @@
<p align="center"><a href="https://www.combodo.com/itop-193" target="_blank">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="/images/logos/logo-itop-baseline-light.svg">
<source media="(prefers-color-scheme: light)" srcset="/images/logos/logo-itop-baseline-dark.svg">
<img src="/images/logos/logo-itop-baseline-light.svg" width="350" alt="Logo iTop with baseline" />
</picture>
<img src="https://www.combodo.com/logos/logo-itop-baseline.svg" width=350>
</a></p>
@@ -94,6 +90,7 @@ We would like to give a special thank you 🤗 to the people from the community
- Dejin, Bie (a.k.a [@bdejin](https://github.com/bdejin))
- Dvořák, Lukáš
- Goethals, Stefan
- Giuva, Vincenzo Katriel (a.k.a [@DarkNight97boss](https://github.com/DarkNight97boss))
- Gumble, David
- Ji, Leeb (冀利斌) (a.k.a [@chileeb](https://github.com/chileeb))
- Kaltefleiter, Lars (a.k.a [@larhip](https://www.github.com/larhip))
@@ -110,7 +107,6 @@ We would like to give a special thank you 🤗 to the people from the community
- Raenker, Martin
- Roháč, Richard (a.k.a [@RohacRichard](https://github.com/RohacRichard))
- Rosenke, Stephan
- Rossi, Tommaso (a.k.a [@tomrss](https://www.github.com/tomrss))
- Rudner, Björn (a.k.a [@rudnerbjoern](https://github.com/rudnerbjoern))
- Šafránek, Jaroslav (a.k.a [jkcinik](https://sourceforge.net/u/jkcinik/profile/) on SourceForge)
- Seki, Shoji
@@ -120,7 +116,6 @@ We would like to give a special thank you 🤗 to the people from the community
- Tarjányi, Csaba (a.k.a [@tacsaby](https://github.com/tacsaby))
- Tulio, Marco
- Turrubiates, Miguel
- Vlk, Karel (a.k.a [@vlk-charles](https://www.github.com/vlk-charles))
### Aliases

View File

@@ -825,37 +825,48 @@ class UserRightsProfile extends UserRightsAddOnAPI
{
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
// We have to answer NO for objects shared for reading purposes
if (self::HasSharing() && SharedObject::GetSharedClassProperties($sClass)) {
// This class is shared, GetSelectFilter may allow some objects for read only
// But currently we are checking whether the objects might be written...
// Let's exclude the objects based on the relevant criteria
if (self::HasSharing())
{
$aClassProps = SharedObject::GetSharedClassProperties($sClass);
if ($aClassProps)
{
// This class is shared, GetSelectFilter may allow some objects for read only
// But currently we are checking wether the objects might be written...
// Let's exclude the objects based on the relevant criteria
// Use $oInstanceSet only if sClass is the main class
if (!is_a($oInstanceSet->GetClass(), $sClass, true)) {
/** @var \DBObjectSet $oInstanceSet */
throw new CoreException(__FUNCTION__.': Expecting object set to be of class '.$sClass.' but it is of class '.$oInstanceSet->GetClass(), ['OQL_Query' => $oInstanceSet->GetFilter()->ToOQL(), 'classes' => $oInstanceSet->GetSelectedClasses()]);
}
$sOrgAttCode = self::GetOwnerOrganizationAttCode($sClass);
if (!is_null($sOrgAttCode)) {
$aUserOrgs = $this->GetUserOrgs($oUser, $sClass);
if (!is_null($aUserOrgs) && count($aUserOrgs) > 0) {
$iCountNO = 0;
$iCountYES = 0;
$oInstanceSet->Rewind();
while ($oObject = $oInstanceSet->Fetch()) {
$iOrg = $oObject->Get($sOrgAttCode);
if (in_array($iOrg, $aUserOrgs)) {
$iCountYES++;
} else {
$iCountNO++;
$sOrgAttCode = self::GetOwnerOrganizationAttCode($sClass);
if (!is_null($sOrgAttCode))
{
$aUserOrgs = $this->GetUserOrgs($oUser, $sClass);
if (!is_null($aUserOrgs) && count($aUserOrgs) > 0)
{
$iCountNO = 0;
$iCountYES = 0;
$oInstanceSet->Rewind();
while($oObject = $oInstanceSet->Fetch())
{
$iOrg = $oObject->Get($sOrgAttCode);
if (in_array($iOrg, $aUserOrgs))
{
$iCountYES++;
}
else
{
$iCountNO++;
}
}
if ($iCountNO == 0)
{
$iPermission = UR_ALLOWED_YES;
}
elseif ($iCountYES == 0)
{
$iPermission = UR_ALLOWED_NO;
}
else
{
$iPermission = UR_ALLOWED_DEPENDS;
}
}
if ($iCountNO == 0) {
$iPermission = UR_ALLOWED_YES;
} elseif ($iCountYES == 0) {
$iPermission = UR_ALLOWED_NO;
} else {
$iPermission = UR_ALLOWED_DEPENDS;
}
}
}
@@ -971,3 +982,4 @@ class UserRightsProfile extends UserRightsAddOnAPI
UserRights::SelectModule('UserRightsProfile');
?>

View File

@@ -399,25 +399,25 @@ class URP_ActionGrant extends UserRightsBaseClass
{
$aParams = array
(
"category" => "addon/userrights",
"key_type" => "autoincrement",
"name_attcode" => "profileid",
"state_attcode" => "",
"reconc_keys" => array(),
"db_table" => "priv_urp_grant_actions",
"db_key_field" => "id",
"category" => "addon/userrights",
"key_type" => "autoincrement",
"name_attcode" => "profileid",
"state_attcode" => "",
"reconc_keys" => array(),
"db_table" => "priv_urp_grant_actions",
"db_key_field" => "id",
"db_finalclass_field" => "",
);
MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes();
// Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked)
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_SILENT, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name")));
MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category" => "", "more_values" => "", "sql" => "class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array(), "class_exclusion_list" => null)));
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values" => new ValueSetEnum('yes,no'), "sql" => "permission", "default_value" => "yes", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "on_target_delete"=>DEL_SILENT, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name")));
MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category"=>"", "more_values"=>"", "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("action", array("allowed_values" => null, "sql" => "action", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeString("action", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
// Display lists
MetaModel::Init_SetZListItems('details', array('profileid', 'class', 'permission', 'action')); // Attributes to be displayed for the complete details
@@ -435,25 +435,25 @@ class URP_StimulusGrant extends UserRightsBaseClass
{
$aParams = array
(
"category" => "addon/userrights",
"key_type" => "autoincrement",
"name_attcode" => "profileid",
"state_attcode" => "",
"reconc_keys" => array(),
"db_table" => "priv_urp_grant_stimulus",
"db_key_field" => "id",
"category" => "addon/userrights",
"key_type" => "autoincrement",
"name_attcode" => "profileid",
"state_attcode" => "",
"reconc_keys" => array(),
"db_table" => "priv_urp_grant_stimulus",
"db_key_field" => "id",
"db_finalclass_field" => "",
);
MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes();
// Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked)
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_SILENT, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name")));
MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category" => "", "more_values" => "", "sql" => "class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array(), "class_exclusion_list" => null)));
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values" => new ValueSetEnum('yes,no'), "sql" => "permission", "default_value" => "yes", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "on_target_delete"=>DEL_SILENT, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name")));
MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category"=>"", "more_values"=>"", "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("stimulus", array("allowed_values" => null, "sql" => "action", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeString("stimulus", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
// Display lists
MetaModel::Init_SetZListItems('details', array('profileid', 'class', 'permission', 'stimulus')); // Attributes to be displayed for the complete details

View File

@@ -402,7 +402,7 @@ class URP_ClassProjection extends UserRightsBaseClass
MetaModel::Init_AddAttribute(new AttributeExternalKey("dimensionid", array("targetclass"=>"URP_Dimensions", "jointype"=> "", "allowed_values"=>null, "sql"=>"dimensionid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("dimension", array("allowed_values"=>null, "extkey_attcode"=> 'dimensionid', "target_attcode"=>"name")));
MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category" => "", "more_values" => "", "sql" => "class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array(), "class_exclusion_list" => null)));
MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category"=>"", "more_values"=>"", "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("value", array("allowed_values"=>null, "sql"=>"value", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("attribute", array("allowed_values"=>null, "sql"=>"attribute", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
@@ -459,25 +459,25 @@ class URP_ActionGrant extends UserRightsBaseClass
{
$aParams = array
(
"category" => "addon/userrights",
"key_type" => "autoincrement",
"name_attcode" => "profileid",
"state_attcode" => "",
"reconc_keys" => array(),
"db_table" => "priv_urp_grant_actions",
"db_key_field" => "id",
"category" => "addon/userrights",
"key_type" => "autoincrement",
"name_attcode" => "profileid",
"state_attcode" => "",
"reconc_keys" => array(),
"db_table" => "priv_urp_grant_actions",
"db_key_field" => "id",
"db_finalclass_field" => "",
);
MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes();
// Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked)
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name")));
MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category" => "", "more_values" => "", "sql" => "class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array(), "class_exclusion_list" => null)));
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values" => new ValueSetEnum('yes,no'), "sql" => "permission", "default_value" => "yes", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name")));
MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category"=>"", "more_values"=>"", "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("action", array("allowed_values" => null, "sql" => "action", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeString("action", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
// Display lists
MetaModel::Init_SetZListItems('details', array('profileid', 'class', 'permission', 'action')); // Attributes to be displayed for the complete details
@@ -495,25 +495,25 @@ class URP_StimulusGrant extends UserRightsBaseClass
{
$aParams = array
(
"category" => "addon/userrights",
"key_type" => "autoincrement",
"name_attcode" => "profileid",
"state_attcode" => "",
"reconc_keys" => array(),
"db_table" => "priv_urp_grant_stimulus",
"db_key_field" => "id",
"category" => "addon/userrights",
"key_type" => "autoincrement",
"name_attcode" => "profileid",
"state_attcode" => "",
"reconc_keys" => array(),
"db_table" => "priv_urp_grant_stimulus",
"db_key_field" => "id",
"db_finalclass_field" => "",
);
MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes();
// Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked)
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name")));
MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category" => "", "more_values" => "", "sql" => "class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array(), "class_exclusion_list" => null)));
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values" => new ValueSetEnum('yes,no'), "sql" => "permission", "default_value" => "yes", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name")));
MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category"=>"", "more_values"=>"", "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("stimulus", array("allowed_values" => null, "sql" => "action", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeString("stimulus", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
// Display lists
MetaModel::Init_SetZListItems('details', array('profileid', 'class', 'permission', 'stimulus')); // Attributes to be displayed for the complete details

View File

@@ -1711,16 +1711,6 @@ interface iRestServiceProvider
public function ExecOperation($sVersion, $sVerb, $aParams);
}
/**
* A REST service provider implementing this interface will have its input JSON data sanitized for logging purposes
* @since 2.7.13, 3.2.1-1
* @see \iRestServiceProvider
*/
interface iRestInputSanitizer
{
public function SanitizeJsonInput(string $sJsonInput): string;
}
/**
* Minimal REST response structure. Derive this structure to add response data and error codes.
*
@@ -1812,14 +1802,6 @@ class RestResult
* @api
*/
public $message;
/**
* Sanitize the content of this result to hide sensitive information
*/
public function SanitizeContent()
{
// The default implementation does nothing
}
}
/**

View File

@@ -698,10 +698,10 @@ HTML
$sLinkedClass = $oAttDef->GetLinkedClass();
// Filter out links pointing to obsolete objects (if relevant)
$oOrmLinkSet = $this->Get($sAttCode);
$oLinkSet = $oOrmLinkSet->ToDBObjectSet(utils::ShowObsoleteData());
$iCount = $oLinkSet->Count();
$oOrmLinkSet = $this->Get($sAttCode);
$oLinkSet = $oOrmLinkSet->ToDBObjectSet(utils::ShowObsoleteData());
$iCount = $oLinkSet->Count();
if ($this->IsNew()) {
$iFlags = $this->GetInitialStateAttributeFlags($sAttCode);
} else {
@@ -766,9 +766,9 @@ HTML
$oPage->add($sHTMLValue);
} else {
if ($oAttDef->IsIndirect()) {
$oBlockLinkSetViewTable = new BlockIndirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef, $bReadOnly, $iCount);
$oBlockLinkSetViewTable = new BlockIndirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef, $bReadOnly);
} else {
$oBlockLinkSetViewTable = new BlockDirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef, $bReadOnly, $iCount);
$oBlockLinkSetViewTable = new BlockDirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef, $bReadOnly);
}
$oPage->AddUiBlock($oBlockLinkSetViewTable);
}
@@ -1113,10 +1113,8 @@ HTML
}
// Note: DisplayBareHeader is called before adding $oObjectDetails to the page, so it can inject HTML before it through $oPage.
/** @var \iTopWebPage $oPage */
$oKPI = new ExecutionKPI();
/** @var iTopWebPage $oPage */
$aHeadersBlocks = $this->DisplayBareHeader($oPage, $bEditMode);
$oKPI->ComputeStatsForExtension($this, 'DisplayBareHeader');
if (false === empty($aHeadersBlocks['subtitle'])) {
$oObjectDetails->AddSubTitleBlocks($aHeadersBlocks['subtitle']);
}
@@ -1129,12 +1127,8 @@ HTML
$oPage->AddTabContainer(OBJECT_PROPERTIES_TAB, '', $oObjectDetails);
$oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB);
$oPage->SetCurrentTab('UI:PropertiesTab');
$oKPI = new ExecutionKPI();
$this->DisplayBareProperties($oPage, $bEditMode);
$oKPI->ComputeStatsForExtension($this, 'DisplayBareProperties');
$oKPI = new ExecutionKPI();
$this->DisplayBareRelations($oPage, $bEditMode);
$oKPI->ComputeStatsForExtension($this, 'DisplayBareRelations');
// Note: Adding the JS snippet which enables the image upload should have been done directly by the ActivityPanel which would have kept the independance principle
@@ -3445,18 +3439,8 @@ EOF
}
$sInputType = '';
$sInputId = 'att_'.$iFieldIndex;
$value = $this->Get($sAttCode);
$sDisplayValue = $this->GetEditValue($sAttCode);
if ($oAttDef instanceof AttributeDateTime && !$oAttDef->IsNullAllowed() && $value === $oAttDef->GetNullValue()) {
$value = $oAttDef->GetDefaultValue($this);
if ($value !== $oAttDef->GetNullValue()) {
// Set default date
$this->Set($sAttCode, $value);
$sDisplayValue = $this->GetEditValue($sAttCode);
}
}
$sHTMLValue = cmdbAbstractObject::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef,
$value, $sDisplayValue, $sInputId, '', $iExpectCode,
$this->Get($sAttCode), $this->GetEditValue($sAttCode), $sInputId, '', $iExpectCode,
$aArgs, true, $sInputType);
$aAttrib = array(
'label' => '<span>'.$oAttDef->GetLabel().'</span>',
@@ -5206,7 +5190,7 @@ HTML
$aKeys = array_keys($aValues[$sAttCode]);
$currValue = $aKeys[0]; // The only value is the first key
if ($oAttDef->GetEditClass() == 'LinkedSet') {
$oOrmLinkSet = $oDummyObj->Get($sAttCode);
$oOrmLinkSet = $oDummyObj->Get($sAttCode);
LinkSetDataTransformer::StringToOrmLinkSet($aValues[$sAttCode][$currValue]['edit_value'], $oOrmLinkSet);
} else {
@@ -5260,7 +5244,7 @@ HTML
}
$oDummyObj->Set($sAttCode, $oTagSet);
} else if ($oAttDef->GetEditClass() == 'LinkedSet') {
$oOrmLinkSet = $oDummyObj->Get($sAttCode);
$oOrmLinkSet = $oDummyObj->Get($sAttCode);
foreach ($aMultiValues as $key => $sValue) {
LinkSetDataTransformer::StringToOrmLinkSet($sValue['edit_value'], $oOrmLinkSet);
}
@@ -5939,14 +5923,14 @@ JS
*
* @since 3.1.0
*/
final protected function FireEventCheckToWrite(?string $sStimulusBeingApplied): void
final protected function FireEventCheckToWrite(): void
{
$this->FireEvent(EVENT_DB_CHECK_TO_WRITE, ['is_new' => $this->IsNew(), 'stimulus_applied' => $sStimulusBeingApplied]);
$this->FireEvent(EVENT_DB_CHECK_TO_WRITE, ['is_new' => $this->IsNew()]);
}
final protected function FireEventBeforeWrite(?string $sStimulusBeingApplied)
final protected function FireEventBeforeWrite()
{
$this->FireEvent(EVENT_DB_BEFORE_WRITE, ['is_new' => $this->IsNew(), 'stimulus_applied' => $sStimulusBeingApplied]);
$this->FireEvent(EVENT_DB_BEFORE_WRITE, ['is_new' => $this->IsNew()]);
}
/**
@@ -5958,11 +5942,11 @@ JS
* @throws \CoreException
* @since 3.1.0
*/
final protected function FireEventAfterWrite(array $aChanges, bool $bIsNew, ?string $sStimulusBeingApplied): void
final protected function FireEventAfterWrite(array $aChanges, bool $bIsNew): void
{
$this->NotifyAttachedObjectsOnLinkClassModification();
$this->RemoveObjectAwaitingEventDbLinksChanged(get_class($this), $this->GetKey());
$this->FireEvent(EVENT_DB_AFTER_WRITE, ['is_new' => $bIsNew, 'changes' => $aChanges, 'stimulus_applied' => $sStimulusBeingApplied]);
$this->FireEvent(EVENT_DB_AFTER_WRITE, ['is_new' => $bIsNew, 'changes' => $aChanges]);
}
//////////////
@@ -6103,9 +6087,7 @@ JS
// We want to avoid launching the listener twice, first here, and secondly after saving the Ticket in the listener
// By disabling the event to be fired, we can remove the current object from the attribute !
$oObject = MetaModel::GetObject($sClass, $sId, false);
if (!is_null($oObject)) {
self::FireEventDbLinksChangedForObject($oObject);
}
self::FireEventDbLinksChangedForObject($oObject);
self::RemoveObjectAwaitingEventDbLinksChanged($sClass, $sId);
}
@@ -6113,11 +6095,13 @@ JS
{
self::SetEventDBLinksChangedBlocked(true);
// N°6408 The object can have been deleted
$oObject->FireEvent(EVENT_DB_LINKS_CHANGED);
if (!is_null($oObject)) {
$oObject->FireEvent(EVENT_DB_LINKS_CHANGED);
// Update the object if needed
if (count($oObject->ListChanges()) !== 0) {
$oObject->DBUpdate();
// Update the object if needed
if (count($oObject->ListChanges()) !== 0) {
$oObject->DBUpdate();
}
}
cmdbAbstractObject::SetEventDBLinksChangedBlocked(false);
}
@@ -6195,9 +6179,9 @@ JS
* @inheritDoc
* @throws \CoreException
*/
final protected function FireEventComputeValues(?string $sStimulusBeingApplied): void
final protected function FireEventComputeValues(): void
{
$this->FireEvent(EVENT_DB_COMPUTE_VALUES, ['is_new' => $this->IsNew(), 'stimulus_applied' => $sStimulusBeingApplied]);
$this->FireEvent(EVENT_DB_COMPUTE_VALUES);
}
/**

View File

@@ -296,21 +296,21 @@ abstract class Dashboard
public function FromParams($aParams)
{
$this->sLayoutClass = $aParams['layout_class'];
if (!is_subclass_of($this->sLayoutClass,DashboardLayout::class)) {
throw new InvalidParameterException('Invalid parameter layout_class "'.$aParams['layout_class'].'"');
}
$this->sTitle = $aParams['title'];
$this->bAutoReload = $aParams['auto_reload'] == 'true';
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int) $aParams['auto_reload_sec']);
foreach($aParams['cells'] as $aCell) {
foreach($aParams['cells'] as $aCell)
{
$aCellDashlets = array();
foreach($aCell as $aDashletParams) {
foreach($aCell as $aDashletParams)
{
$sDashletClass = $aDashletParams['dashlet_class'];
$sId = $aDashletParams['dashlet_id'];
/** @var \Dashlet $oNewDashlet */
$oNewDashlet = new $sDashletClass($this->oMetaModel, $sId);
if (isset($aDashletParams['dashlet_type'])) {
if (isset($aDashletParams['dashlet_type']))
{
$oNewDashlet->SetDashletType($aDashletParams['dashlet_type']);
}
$oForm = $oNewDashlet->GetForm();
@@ -1266,12 +1266,13 @@ EOF
$sOkButtonLabel = Dict::S('UI:Button:Save');
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
$sId = json_encode($this->sId);
$sLayoutClass = json_encode($this->sLayoutClass);
$sId = utils::HtmlEntities($this->sId);
$sLayoutClass = utils::HtmlEntities($this->sLayoutClass);
$sAutoReload = $this->bAutoReload ? 'true' : 'false';
$sAutoReloadSec = (string) $this->iAutoReloadSec;
$sTitle = json_encode($this->sTitle);
$sFile = json_encode($this->GetDefinitionFile());
$sTitle = utils::HtmlEntities($this->sTitle);
$sFile = utils::HtmlEntities($this->GetDefinitionFile());
$sFileForJS = json_encode($this->GetDefinitionFile());
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php';
$sReloadURL = $this->GetReloadURL();
@@ -1327,15 +1328,15 @@ $('#dashboard_editor').dialog({
});
$('#dashboard_editor .ui-layout-center').runtimedashboard({
dashboard_id: $sId,
layout_class: $sLayoutClass,
title: $sTitle,
dashboard_id: '$sId',
layout_class: '$sLayoutClass',
title: '$sTitle',
auto_reload: $sAutoReload,
auto_reload_sec: $sAutoReloadSec,
submit_to: '$sUrl',
submit_parameters: {operation: 'save_dashboard', file: $sFile, extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
submit_parameters: {operation: 'save_dashboard', file: {$sFileForJS}, extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
render_to: '$sUrl',
render_parameters: {operation: 'render_dashboard', file: $sFile, extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
render_parameters: {operation: 'render_dashboard', file: {$sFileForJS}, extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
new_dashlet_parameters: {operation: 'new_dashlet'}
});

View File

@@ -238,10 +238,6 @@ The object can be modified.]]></description>
<description>Creation flag</description>
<type>boolean</type>
</event_datum>
<event_datum id="stimulus_applied">
<description>Life cycle stimulus applied (null if not within a transition)</description>
<type>string</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
@@ -267,10 +263,6 @@ Call $this->AddCheckWarning($sWarningMessage) to display a warning.
<description>Creation flag</description>
<type>boolean</type>
</event_datum>
<event_datum id="stimulus_applied">
<description>Life cycle stimulus applied (null if not within a transition)</description>
<type>string</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
@@ -298,10 +290,6 @@ The modifications can be propagated to other objects.]]></description>
<description><![CDATA[For updates, the list of changes done during this operation]]></description>
<type>array</type>
</event_datum>
<event_datum id="stimulus_applied">
<description>Life cycle stimulus applied (null if not within a transition)</description>
<type>string</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
@@ -432,14 +420,6 @@ The only action allowed is to deny transitions with $this->DenyTransition($sTran
<description>The object inserted</description>
<type>DBObject</type>
</event_datum>
<event_datum id="is_new">
<description>Creation flag</description>
<type>boolean</type>
</event_datum>
<event_datum id="stimulus_applied">
<description>Life cycle stimulus applied (null if not within a transition)</description>
<type>string</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>

View File

@@ -263,8 +263,6 @@ class DisplayBlock
/** param for export.php */
'refresh_action',
/**to add refresh button in datatable*/
'object_count',
/** int number of objects in list */
], DataTableUIBlockFactory::GetAllowedParams()),
static::ENUM_STYLE_LIST_SEARCH => array_merge([
'update_history',
@@ -1862,11 +1860,7 @@ class MenuBlock extends DisplayBlock
$aSelectedClasses = $this->GetFilter()->GetSelectedClasses();
$bIsForLinkset = isset($aExtraParams['target_attr']);
$oSet = new CMDBObjectSet($this->GetFilter());
if(isset($aExtraParams['object_count'])){
$iSetCount = $aExtraParams['object_count'];
} else {
$iSetCount = $oSet->Count();
}
$iSetCount = $oSet->Count();
/** @var string $sRefreshAction JS snippet to run when clicking on the refresh button of the menu */
$sRefreshAction = $aExtraParams['refresh_action'] ?? '';
$bIsCreationInModal = isset($aExtraParams['creation_in_modal']) && $aExtraParams['creation_in_modal'] === true;
@@ -2030,8 +2024,8 @@ class MenuBlock extends DisplayBlock
$sSelectedClassName = MetaModel::GetName($sSelectedClass);
// Check rights on class
$bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sSelectedClass)) && UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_MODIFY) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
$bIsBulkDeleteAllowed = (bool) UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_DELETE);
$bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sSelectedClass)) && UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_MODIFY, $oSet) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
$bIsBulkDeleteAllowed = (bool) UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_DELETE, $sSelectedClass);
// Refine filter on selected class so bullk actions occur on the right class
$oSelectedClassFilter = $this->GetFilter()->DeepClone();

View File

@@ -36,30 +36,29 @@ class InputOutputTask extends cmdbAbstractObject
{
$aParams = array
(
"category" => "application",
"key_type" => "autoincrement",
"name_attcode" => "name",
"state_attcode" => "",
"reconc_keys" => array(),
"db_table" => "priv_iotask",
"db_key_field" => "id",
"category" => "application",
"key_type" => "autoincrement",
"name_attcode" => "name",
"state_attcode" => "",
"reconc_keys" => array(),
"db_table" => "priv_iotask",
"db_key_field" => "id",
"db_finalclass_field" => "",
);
MetaModel::Init_Params($aParams);
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeEnum("category", array("allowed_values" => new ValueSetEnum('Input, Ouput'), "sql" => "category", "default_value" => "Input", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeEnum("source_type", array("allowed_values" => new ValueSetEnum('File, Database, Web Service'), "sql" => "source_type", "default_value" => "File", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeEnum("source_subtype",
array("allowed_values" => new ValueSetEnum('Oracle, MySQL, Postgress, MSSQL, SOAP, HTTP-Get, HTTP-Post, XML/RPC, CSV, XML, Excel'), "sql" => "source_subtype", "default_value" => "CSV", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeString("source_path", array("allowed_values" => null, "sql" => "source_path", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeClass("objects_class", array("class_category" => "", "more_values" => "", "sql" => "objects_class", "default_value" => null, "is_null_allowed" => true, "depends_on" => array(), "class_exclusion_list" => null)));
MetaModel::Init_AddAttribute(new AttributeEnum("test_mode", array("allowed_values" => new ValueSetEnum('Yes,No'), "sql" => "test_mode", "default_value" => 'No', "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeEnum("verbose_mode", array("allowed_values" => new ValueSetEnum('Yes,No'), "sql" => "verbose_mode", "default_value" => 'No', "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeEnum("options", array("allowed_values" => new ValueSetEnum('Full, Update Only, Creation Only'), "sql" => "options", "default_value" => 'Full', "is_null_allowed" => true, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeEnum("category", array("allowed_values"=>new ValueSetEnum('Input, Ouput'), "sql"=>"category", "default_value"=>"Input", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeEnum("source_type", array("allowed_values"=>new ValueSetEnum('File, Database, Web Service'), "sql"=>"source_type", "default_value"=>"File", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeEnum("source_subtype", array("allowed_values"=>new ValueSetEnum('Oracle, MySQL, Postgress, MSSQL, SOAP, HTTP-Get, HTTP-Post, XML/RPC, CSV, XML, Excel'), "sql"=>"source_subtype", "default_value"=>"CSV", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("source_path", array("allowed_values"=>null, "sql"=>"source_path", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeClass("objects_class", array("class_category"=>"", "more_values"=>"", "sql"=>"objects_class", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeEnum("test_mode", array("allowed_values"=>new ValueSetEnum('Yes,No'), "sql"=>"test_mode", "default_value"=>'No', "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeEnum("verbose_mode", array("allowed_values"=>new ValueSetEnum('Yes,No'), "sql"=>"verbose_mode", "default_value" => 'No', "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeEnum("options", array("allowed_values"=>new ValueSetEnum('Full, Update Only, Creation Only'), "sql"=>"options", "default_value"=> 'Full', "is_null_allowed"=>true, "depends_on"=>array())));
// Display lists
MetaModel::Init_SetZListItems('details', array('name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype', 'source_path', 'options', 'test_mode', 'verbose_mode')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype', 'source_path' , 'options', 'test_mode', 'verbose_mode')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('description', 'category', 'objects_class', 'source_type', 'source_subtype', 'options')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('name', 'category', 'objects_class', 'source_type', 'source_subtype')); // Criteria of the std search form

View File

@@ -1159,11 +1159,11 @@ class OQLMenuNode extends MenuNode
{
$sUsageId = utils::GetSafeId($sUsageId);
$oSearch = DBObjectSearch::FromOQL($sOql);
$sClass= $oSearch->GetClass();
$sClass= $oSearch->GetClass();
$sIcon = MetaModel::GetClassIcon($sClass, false);
if ($bSearchPane) {
$aParams = array_merge(['open' => $bSearchOpen, 'table_id' => $sUsageId, 'submit_on_load' => false], $aExtraParams);
$oBlock = new DisplayBlock($oSearch, DisplayBlock::ENUM_STYLE_SEARCH, false /* Asynchronous */, $aParams);
$oBlock = new DisplayBlock($oSearch, 'search', false /* Asynchronous */, $aParams);
$oBlock->Display($oPage, 0);
$oPage->add("<div class='sf_results_area ibo-add-margin-top-250' data-target='search_results'>");
}

View File

@@ -249,9 +249,9 @@ class appUserPreferences extends DBObject
(
"category" => "gui",
"key_type" => "autoincrement",
"name_attcode" => "login",
"name_attcode" => "userid",
"state_attcode" => "",
"reconc_keys" => array("userid","login"),
"reconc_keys" => array("userid"),
"db_table" => "priv_app_preferences",
"db_key_field" => "id",
"db_finalclass_field" => "",
@@ -260,10 +260,8 @@ class appUserPreferences extends DBObject
MetaModel::Init_Params($aParams);
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributePropertySet("preferences", array("allowed_values"=>null, "sql"=>"preferences", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("org_id", array("allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "org_id")));
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login")));
MetaModel::Init_SetZListItems('list', array('org_id','preferences'));
MetaModel::Init_SetZListItems('default_search', array('userid','login','org_id'));
MetaModel::Init_SetZListItems('list', array('preferences',));
MetaModel::Init_SetZListItems('default_search', array('userid'));
}
/**

View File

@@ -180,7 +180,6 @@ class utils
*/
private static $sAbsoluteUrlAppRootCache = null;
protected static function LoadParamFile($sParamFile)
{
if (!file_exists($sParamFile)) {
@@ -419,26 +418,11 @@ class utils
* @since 2.7.7, 3.0.2, 3.1.0 N°4899 - new 'url' filter
* @since 2.7.10 N°6606 use the utils::ENUM_SANITIZATION_* const
* @since 2.7.10 N°6606 new case for ENUM_SANITIZATION_FILTER_PHP_CLASS
* @since 3.2.1-1 N°8242 Allow value to be an array for every filter
*
* @link https://www.php.net/manual/en/filter.filters.sanitize.php PHP sanitization filters
*/
protected static function Sanitize_Internal($value, $sSanitizationFilter)
{
if (is_array($value))
{
$retValue = array();
foreach ($value as $key => $val)
{
$retValue[$key] = self::Sanitize_Internal($val, $sSanitizationFilter); // recursively check arrays
if ($retValue[$key] === false)
{
return false;
}
}
return $retValue;
}
switch ($sSanitizationFilter)
{
case static::ENUM_SANITIZATION_FILTER_INTEGER:
@@ -469,36 +453,52 @@ class utils
case static::ENUM_SANITIZATION_FILTER_PARAMETER:
case static::ENUM_SANITIZATION_FILTER_FIELD_NAME:
case static::ENUM_SANITIZATION_FILTER_TRANSACTION_ID:
switch ($sSanitizationFilter)
if (is_array($value))
{
case static::ENUM_SANITIZATION_FILTER_TRANSACTION_ID:
// Same as parameter type but keep the dot character
// transaction_id, the dot is mostly for Windows servers when using file storage as the tokens are named *.tmp
// - See N°1835
// - Note: It must be included at the regexp beginning otherwise you'll get an invalid character error
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[\. A-Za-z0-9_=-]*$/')));
break;
$retValue = array();
foreach ($value as $key => $val)
{
$retValue[$key] = self::Sanitize_Internal($val, $sSanitizationFilter); // recursively check arrays
if ($retValue[$key] === false)
{
$retValue = false;
break;
}
}
}
else
{
switch ($sSanitizationFilter)
{
case static::ENUM_SANITIZATION_FILTER_TRANSACTION_ID:
// Same as parameter type but keep the dot character
// transaction_id, the dot is mostly for Windows servers when using file storage as the tokens are named *.tmp
// - See N°1835
// - Note: It must be included at the regexp beginning otherwise you'll get an invalid character error
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[\. A-Za-z0-9_=-]*$/')));
break;
case static::ENUM_SANITIZATION_FILTER_ROUTE:
case static::ENUM_SANITIZATION_FILTER_OPERATION:
// - Routes should be of the "controller_namespace_code.controller_method_name" form
// - Operations should be allowed to be namespaced as well even though then don't have dedicated controller yet
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[\.A-Za-z0-9_-]*$/')));
break;
case static::ENUM_SANITIZATION_FILTER_ROUTE:
case static::ENUM_SANITIZATION_FILTER_OPERATION:
// - Routes should be of the "controller_namespace_code.controller_method_name" form
// - Operations should be allowed to be namespaced as well even though then don't have dedicated controller yet
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[\.A-Za-z0-9_-]*$/')));
break;
case static::ENUM_SANITIZATION_FILTER_PARAMETER:
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[ A-Za-z0-9_=-]*$/'))); // the '=', '%3D, '%2B', '%2F'
// Characters are used in serialized filters (starting 2.5, only the url encoded versions are presents, but the "=" is kept for BC)
break;
case static::ENUM_SANITIZATION_FILTER_PARAMETER:
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[ A-Za-z0-9_=-]*$/'))); // the '=', '%3D, '%2B', '%2F'
// Characters are used in serialized filters (starting 2.5, only the url encoded versions are presents, but the "=" is kept for BC)
break;
case static::ENUM_SANITIZATION_FILTER_FIELD_NAME:
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[A-Za-z0-9_]+(->[A-Za-z0-9_]+)*$/'))); // att_code or att_code->name or AttCode->Name or AttCode->Key2->Name
break;
case static::ENUM_SANITIZATION_FILTER_FIELD_NAME:
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[A-Za-z0-9_]+(->[A-Za-z0-9_]+)*$/'))); // att_code or att_code->name or AttCode->Name or AttCode->Key2->Name
break;
case static::ENUM_SANITIZATION_FILTER_CONTEXT_PARAM:
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[ A-Za-z0-9_=%:+-]*$/')));
break;
case static::ENUM_SANITIZATION_FILTER_CONTEXT_PARAM:
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[ A-Za-z0-9_=%:+-]*$/')));
break;
}
}
break;
@@ -1451,12 +1451,9 @@ class utils
* @return string A path to a folder into which any module can store cache data
* The corresponding folder is created or cleaned upon code compilation
*/
public static function GetCachePath(string $sEnvironment = null): string
public static function GetCachePath()
{
if (is_null($sEnvironment)) {
$sEnvironment = MetaModel::GetEnvironment();
}
return static::GetDataPath()."cache-$sEnvironment/";
return static::GetDataPath().'cache-'.MetaModel::GetEnvironment().'/';
}
/**
@@ -2393,75 +2390,53 @@ SQL;
return $bRet;
}
/**
* @param $sPath
*
* @return false|\ormDocument
* @throws \Exception
*
* @deprecated 3.2.1 use utils::GetDocumentFromSelfURL instead
*/
public static function IsSelfURL($sPath)
{
return self::GetDocumentFromSelfURL($sPath);
}
/**
* Check if the given URL is a link to download a document/image on the CURRENT iTop
* In such a case we can read the content of the file directly in the database (if the users rights allow) and return the ormDocument
*
* @Since 3.2.1 a local URL is transformed into a local file to read
*
* @param string $sPath
* @return false|ormDocument
* @throws Exception
*/
public static function GetDocumentFromSelfURL(string $sPath)
public static function IsSelfURL($sPath)
{
$result = false;
$sPageUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.document.php';
if (utils::StartsWith($sPath, $sPageUrl)) {
if (substr($sPath, 0, strlen($sPageUrl)) == $sPageUrl)
{
// If the URL is an URL pointing to this instance of iTop, then
// extract the "query" part of the URL and analyze it
$sQuery = parse_url($sPath, PHP_URL_QUERY);
if ($sQuery !== null) {
if ($sQuery !== null)
{
$aParams = array();
foreach (explode('&', $sQuery) as $sChunk) {
foreach(explode('&', $sQuery) as $sChunk)
{
$aParts = explode('=', $sChunk ?? '');
if (count($aParts) != 2) {
continue;
}
if (count($aParts) != 2) continue;
$aParams[$aParts[0]] = urldecode($aParts[1]);
}
$result = array_key_exists('operation', $aParams) && array_key_exists('class', $aParams) && array_key_exists('id', $aParams) && array_key_exists('field', $aParams) && ($aParams['operation'] == 'download_document');
if ($result) {
if ($result)
{
// This is a 'download_document' operation, let's retrieve the document directly from the database
$sClass = $aParams['class'];
$iKey = $aParams['id'];
$sAttCode = $aParams['field'];
$oObj = MetaModel::GetObject($sClass, $iKey, false /* must exist */); // Users rights apply here !!
if ($oObj) {
if ($oObj)
{
/**
* @var ormDocument $result
*/
return clone $oObj->Get($sAttCode);
$result = clone $oObj->Get($sAttCode);
return $result;
}
}
}
throw new Exception('Invalid URL. This iTop URL is not pointing to a valid Document/Image.');
}
if (utils::StartsWith($sPath, utils::GetAbsoluteUrlAppRoot())) {
$sFilePath = utils::LocalPath(APPROOT.substr($sPath, strlen(utils::GetAbsoluteUrlAppRoot())));
if (false === $sFilePath) {
return false;
}
$sFilePath = APPROOT.$sFilePath;
return ormDocument::FromFile($sFilePath);
}
return false;
return $result;
}
/**
@@ -2469,28 +2444,68 @@ SQL;
* - an URL pointing to a blob (image/document) on the current iTop server
* - an http(s) URL
* - the local file system (but only if you are an administrator)
*
* @param string|null $sPath
* @param string $sPath
* @return ormDocument|null
* @throws Exception
*/
public static function FileGetContentsAndMIMEType($sPath)
{
if (utils::IsNullOrEmptyString($sPath)) {
$oUploadedDoc = null;
$aKnownExtensions = array(
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
'pdf' => 'application/pdf',
'doc' => 'application/msword',
'dot' => 'application/msword',
'xls' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint',
'vsd' => 'application/x-visio',
'vdx' => 'application/visio.drawing',
'odt' => 'application/vnd.oasis.opendocument.text',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'zip' => 'application/zip',
'txt' => 'text/plain',
'htm' => 'text/html',
'html' => 'text/html',
'exe' => 'application/octet-stream',
);
$sData = null;
$sMimeType = 'text/plain'; // Default MIME Type: treat the file as a bunch a characters...
$sFileName = 'uploaded-file'; // Default name for downloaded-files
$sExtension = '.txt'; // Default file extension in case we don't know the MIME Type
if(empty($sPath))
{
// Empty path (NULL or '') means that there is no input, making an empty document.
return new ormDocument('', '', '');
$oUploadedDoc = new ormDocument('', '', '');
}
if (static::IsURL($sPath)) {
$oUploadedDoc = static::GetDocumentFromSelfURL($sPath);
if ($oUploadedDoc) {
return $oUploadedDoc;
elseif (static::IsURL($sPath))
{
if ($oUploadedDoc = static::IsSelfURL($sPath))
{
// Nothing more to do, we've got it !!
}
// Remote file, let's use the HTTP headers to find the MIME Type
$sData = @file_get_contents($sPath);
if ($sData === false) {
IssueLog::Error(<<<TXT
else
{
// Remote file, let's use the HTTP headers to find the MIME Type
$sData = @file_get_contents($sPath);
if ($sData === false)
{
IssueLog::Error(<<<TXT
Failed to load the file from URL. This can happen for multiple reasons:
- Invalid URL
- URL using HTTPS with an untrusted certificate on the remote server
@@ -2499,40 +2514,54 @@ TXT
, LogChannels::CORE, [
'URL' => $sPath,
]);
throw new Exception("Failed to load the file from the URL '$sPath'.");
}
$sMimeType = 'text/plain'; // Default MIME Type: treat the file as a bunch a characters...
$sFileName = 'uploaded-file'; // Default name for downloaded-files
$sExtension = '.txt'; // Default file extension in case we don't know the MIME Type
if (isset($http_response_header)) {
$aHeaders = static::ParseHeaders($http_response_header);
$sMimeType = array_key_exists('Content-Type', $aHeaders) ? strtolower($aHeaders['Content-Type']) : 'application/x-octet-stream';
// Compute the file extension from the MIME Type
foreach (ormDocument::GetKnownExtensions() as $sExtValue => $sMime) {
if ($sMime === $sMimeType) {
$sExtension = '.'.$sExtValue;
break;
}
throw new Exception("Failed to load the file from the URL '$sPath'.");
}
else
{
if (isset($http_response_header))
{
$aHeaders = static::ParseHeaders($http_response_header);
$sMimeType = array_key_exists('Content-Type', $aHeaders) ? strtolower($aHeaders['Content-Type']) : 'application/x-octet-stream';
// Compute the file extension from the MIME Type
foreach ($aKnownExtensions as $sExtValue => $sMime) {
if ($sMime === $sMimeType) {
$sExtension = '.'.$sExtValue;
break;
}
}
}
$sPathName = pathinfo($sPath, PATHINFO_FILENAME);
if (utils::IsNotNullOrEmptyString($sPathName)) {
$sFileName = $sPathName;
}
$sFileName .= $sExtension;
}
$oUploadedDoc = new ormDocument($sData, $sMimeType, $sFileName);
}
$sPathName = pathinfo($sPath, PATHINFO_FILENAME);
if (utils::IsNotNullOrEmptyString($sPathName)) {
$sFileName = $sPathName;
}
$sFileName .= $sExtension;
return new ormDocument($sData, $sMimeType, $sFileName);
}
// Local file
if (UserRights::IsAdministrator()) {
else if (UserRights::IsAdministrator())
{
// Only administrators are allowed to read local files
return ormDocument::FromFile($sPath);
}
$sData = @file_get_contents($sPath);
if ($sData === false)
{
throw new Exception("Failed to load the file '$sPath'. The file does not exist or the current process is not allowed to access it.");
}
$sExtension = strtolower(pathinfo($sPath, PATHINFO_EXTENSION));
$sFileName = basename($sPath);
return null;
if (array_key_exists($sExtension, $aKnownExtensions))
{
$sMimeType = $aKnownExtensions[$sExtension];
}
else if (extension_loaded('fileinfo'))
{
$finfo = new finfo(FILEINFO_MIME);
$sMimeType = $finfo->file($sPath);
}
$oUploadedDoc = new ormDocument($sData, $sMimeType, $sFileName);
}
return $oUploadedDoc;
}
protected static function ParseHeaders($aHeaders)
@@ -3103,13 +3132,30 @@ TXT
* @throws \Exception
* @since 3.0.0
*/
public static function GetMentionedObjectsFromText(string $sText): array
public static function GetMentionedObjectsFromText(string $sText, string $sFormat = self::ENUM_TEXT_FORMAT_HTML): array
{
$aMentionedObjects = [];
$aMentionMatches = [];
$sText = html_entity_decode($sText);
// First transform text so it can be parsed
switch ($sFormat) {
case static::ENUM_TEXT_FORMAT_HTML:
$sText = static::HtmlToText($sText);
break;
default:
// Don't transform it
break;
}
// Then parse text to find objects
$aMentionedObjects = array();
$aMentionMatches = array();
// Note: As the sanitizer (or CKEditor autocomplete plugin? 🤔) removes data-* attributes from the hyperlink,
// - we can't use the following (simpler) regexp that only checks data attributes on hyperlinks, which would have worked for hyperlinks pointing to any GUIs: '/<a\s*([^>]*)data-object-class="([^"]*)"\s*data-object-id="([^"]*)">/i'
// - instead we use a regexp to match the following pattern '[Some object label](<APP_ROOT_URL>...&class=<OBJECT_CLASS>&id=<OBJECT_ID>...)' which only works for the backoffice
// If we change the sanitizer, we might want to switch to the other regexp as it's universal and easier to read
$sAppRootUrlForRegExp = addcslashes(utils::GetAbsoluteUrlAppRoot(), '/&');
preg_match_all("/\[([^\]]*)\]\({$sAppRootUrlForRegExp}[^\)]*\&class=([^\)\&]*)\&id=([\d]*)[^\)]*\)/i", $sText, $aMentionMatches);
preg_match_all('/<a\s*([^>]*)data-object-class="([^"]*)"\s.*data-object-key="([^"]*)"/Ui', $sText, $aMentionMatches);
foreach ($aMentionMatches[0] as $iMatchIdx => $sCompleteMatch) {
$sMatchedClass = $aMentionMatches[2][$iMatchIdx];
$sMatchedId = $aMentionMatches[3][$iMatchIdx];

View File

@@ -11,7 +11,7 @@ define('APPCONF', APPROOT.'conf/');
*
* @see ITOP_CORE_VERSION to get full iTop core version
*/
define('ITOP_DESIGN_LATEST_VERSION', '3.2');
define('ITOP_DESIGN_LATEST_VERSION', '3.3');
/**
* Constant containing the iTop core version, whatever application was built
@@ -23,7 +23,7 @@ define('ITOP_DESIGN_LATEST_VERSION', '3.2');
* @used-by utils::GetItopVersionWikiSyntax()
* @used-by iTopModulesPhpVersionIntegrationTest
*/
define('ITOP_CORE_VERSION', '3.2.1');
define('ITOP_CORE_VERSION', '3.3.0');
/**
* @var string

102
composer.lock generated
View File

@@ -3929,82 +3929,6 @@
],
"time": "2023-01-26T09:26:14+00:00"
},
{
"name": "symfony/polyfill-php81",
"version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php81.git",
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php81\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-php83",
"version": "v1.28.0",
@@ -5052,38 +4976,30 @@
},
{
"name": "twig/twig",
"version": "v3.16.0",
"version": "v3.8.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "475ad2dc97d65d8631393e721e7e44fb544f0561"
"reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/475ad2dc97d65d8631393e721e7e44fb544f0561",
"reference": "475ad2dc97d65d8631393e721e7e44fb544f0561",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/9d15f0ac07f44dc4217883ec6ae02fd555c6f71d",
"reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d",
"shasum": ""
},
"require": {
"php": ">=8.0.2",
"symfony/deprecation-contracts": "^2.5|^3",
"php": ">=7.2.5",
"symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-mbstring": "^1.3",
"symfony/polyfill-php81": "^1.29"
"symfony/polyfill-php80": "^1.22"
},
"require-dev": {
"phpstan/phpstan": "^2.0",
"psr/container": "^1.0|^2.0",
"symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0"
"symfony/phpunit-bridge": "^5.4.9|^6.3|^7.0"
},
"type": "library",
"autoload": {
"files": [
"src/Resources/core.php",
"src/Resources/debug.php",
"src/Resources/escaper.php",
"src/Resources/string_loader.php"
],
"psr-4": {
"Twig\\": "src/"
}
@@ -5116,7 +5032,7 @@
],
"support": {
"issues": "https://github.com/twigphp/Twig/issues",
"source": "https://github.com/twigphp/Twig/tree/v3.16.0"
"source": "https://github.com/twigphp/Twig/tree/v3.8.0"
},
"funding": [
{
@@ -5128,7 +5044,7 @@
"type": "tidelift"
}
],
"time": "2024-11-29T08:27:05+00:00"
"time": "2023-11-21T18:54:41+00:00"
},
{
"name": "webmozart/assert",

View File

@@ -181,7 +181,7 @@ abstract class Action extends cmdbAbstractObject
{
parent::DisplayBareRelations($oPage, false);
if ($oPage instanceof iTopWebPage && !$this->IsNew()) {
if ($oPage instanceof iTopWebPage) {
$this->GenerateLastExecutionsTab($oPage, $bEditMode);
}
}

View File

@@ -89,7 +89,7 @@ abstract class AsyncTask extends DBObject
// The value is set from null to planned in the setup program
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("allowed_values"=>new ValueSetEnum('planned,running,idle,error'), "sql"=>"status", "default_value"=>"planned", "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("created", array("allowed_values"=>null, "sql"=>"created", "default_value"=>"NOW()", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("created", array("allowed_values"=>null, "sql"=>"created", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("started", array("allowed_values"=>null, "sql"=>"started", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("planned", array("allowed_values"=>null, "sql"=>"planned", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalKey("event_id", array("targetclass"=>"Event", "jointype"=> "", "allowed_values"=>null, "sql"=>"event_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_SILENT, "depends_on"=>array())));
@@ -489,7 +489,7 @@ class AsyncSendNewsroom extends AsyncTask {
MetaModel::Init_AddAttribute(new AttributeInteger("object_id", array("allowed_values"=>null, "sql"=>"object_id", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("object_class", array("allowed_values"=>null, "sql"=>"object_class", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("url", array("allowed_values"=>null, "sql"=>"url", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>'NOW()', "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
}

View File

@@ -142,7 +142,7 @@ abstract class AttributeDefinition
protected $aCSSClasses;
public function GetType()
public function GetType()
{
return Dict::S('Core:'.get_class($this));
}
@@ -1715,8 +1715,8 @@ class AttributeLinkedSet extends AttributeDefinition
public function GetEditMode()
{
return $this->GetOptional('edit_mode', LINKSET_EDITMODE_ACTIONS);
}
}
/**
* @return int see LINKSET_EDITWHEN_* constants
* @since 3.1.1 3.2.0 N°6385
@@ -1758,7 +1758,7 @@ class AttributeLinkedSet extends AttributeDefinition
{
return $this->GetOptional('with_php_computation', false);
}
public function GetLinkedClass()
{
return $this->Get('linked_class');
@@ -3793,7 +3793,7 @@ class AttributeClass extends AttributeString
public static function ListExpectedParams()
{
return array_merge(parent::ListExpectedParams(), array('class_category', 'more_values'));
return array_merge(parent::ListExpectedParams(), array("class_category", "more_values"));
}
public function __construct($sCode, $aParams)
@@ -3819,35 +3819,10 @@ class AttributeClass extends AttributeString
return $sDefault;
}
/**
* @param array $aArgs
* @param string $sContains
*
* @return array|null
* @throws \CoreException
*/
public function GetAllowedValues($aArgs = array(), $sContains = '')
{
$oValSetDef = $this->GetValuesDef();
if (!$oValSetDef) {
return null;
}
$aListClass = $oValSetDef->GetValues($aArgs, $sContains);
/* @since 3.3.0 remove elements in class_exclusion_list*/
$sClassExclusionList = $this->GetOptional('class_exclusion_list',null);
if (!empty($sClassExclusionList)) {
foreach (explode(',', $sClassExclusionList) as $sClassName) {
unset($aListClass[trim($sClassName)]);
}
}
return $aListClass;
}
public function GetAsHTML($sValue, $oHostObject = null, $bLocalize = true)
{
if (empty($sValue)) {
if (empty($sValue))
{
return '';
}
@@ -4218,7 +4193,7 @@ class AttributeFinalClass extends AttributeString
*/
class AttributePassword extends AttributeString implements iAttributeNoGroupBy
{
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
/**
* Useless constructor, but if not present PHP 7.4.0/7.4.1 is crashing :( (N°2329)
@@ -4295,7 +4270,7 @@ class AttributePassword extends AttributeString implements iAttributeNoGroupBy
*/
class AttributeEncryptedString extends AttributeString implements iAttributeNoGroupBy
{
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
protected function GetSQLCol($bFullSpec = false)
{
@@ -4465,7 +4440,7 @@ class AttributeText extends AttributeString
{
// Is there a way to know the current limitation for mysql?
// See mysql_field_len()
return 16383; // number of characters (that can be 1-4 bytes long), not of bytes
return 65535;
}
public static function RenderWikiHtml($sText, $bWikiOnly = false)
@@ -6371,15 +6346,10 @@ class AttributeDateTime extends AttributeDBField
$oFormField = parent::MakeFormField($oObject, $oFormField);
// After call to the parent as it sets the current value
$oValue = $oObject->Get($this->GetCode());
if ($oValue === $this->GetNullValue()) {
$oValue = $this->GetDefaultValue($oObject);
}
$oFormField->SetCurrentValue($this->GetFormat()->Format($oValue));
// After call to the parent as it sets the current value
$oFormField->SetCurrentValue($this->GetFormat()->Format($oObject->Get($this->GetCode())));
return $oFormField;
return $oFormField;
}
/**
@@ -6463,26 +6433,8 @@ class AttributeDateTime extends AttributeDBField
public function GetDefaultValue(DBObject $oHostObject = null)
{
$sDefaultValue = $this->Get('default_value');
if (utils::IsNotNullOrEmptyString($sDefaultValue)) {
try {
$sDefaultDate = Expression::FromOQL($sDefaultValue)->Evaluate([]);
} catch (Exception $e) {
try {
$sDefaultDate = Expression::FromOQL('"'.$sDefaultValue.'"')->Evaluate([]);
} catch (Exception $e) {
IssueLog::Error("Invalid default value '$sDefaultValue' for field '{$this->GetCode()}' on class '{$this->GetHostClass()}', defaulting to null");
return $this->GetNullValue();
}
}
try {
$oDate = new DateTimeImmutable($sDefaultDate);
} catch (Exception $e) {
IssueLog::Error("Invalid default value '$sDefaultValue' for field '{$this->GetCode()}' on class '{$this->GetHostClass()}', defaulting to null");
return $this->GetNullValue();
}
return $oDate->format($this->GetInternalFormat());
if (!$this->IsNullAllowed()) {
return date($this->GetInternalFormat());
}
return $this->GetNullValue();
}
@@ -9481,13 +9433,8 @@ class AttributeStopWatch extends AttributeDefinition
case 'deadline':
if ($value)
{
if (is_int($value))
{
$sDate = date(AttributeDateTime::GetInternalFormat(), $value);
$sRet = AttributeDeadline::FormatDeadline($sDate);
} else {
$sRet = $value;
}
$sDate = date(AttributeDateTime::GetInternalFormat(), $value);
$sRet = AttributeDeadline::FormatDeadline($sDate);
}
else
{
@@ -10037,7 +9984,7 @@ class AttributeSubItem extends AttributeDefinition
*/
class AttributeOneWayPassword extends AttributeDefinition implements iAttributeNoGroupBy
{
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
/**
* Useless constructor, but if not present PHP 7.4.0/7.4.1 is crashing :( (N°2329)

View File

@@ -519,7 +519,7 @@ class BulkChange
foreach ($this->m_aExtKeys[$sAttCode] as $sForeignAttCode => $iCol)
{
// The foreign attribute is one of our reconciliation key
if (isset($aRowData[$iCol]) && strlen($aRowData[$iCol]) > 0)
if (strlen($aRowData[$iCol]) > 0)
{
return false;
}
@@ -1181,9 +1181,6 @@ class BulkChange
foreach($this->m_aData as $iRow => $aRowData)
{
$sFormat = $sDateTimeFormat;
if(!isset($this->m_aData[$iRow][$iCol])){
continue;
}
$sValue = $this->m_aData[$iRow][$iCol];
if (!empty($sValue))
{
@@ -1236,22 +1233,11 @@ class BulkChange
$iPreviousTimeLimit = ini_get('max_execution_time');
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
$iNBFields = count($this->m_aAttList);
foreach ($this->m_aExtKeys as $aReconcilKeys) {
$iNBFields += count($aReconcilKeys);
}
// Avoid too many events
cmdbAbstractObject::SetEventDBLinksChangedBlocked(true);
try {
foreach ($this->m_aData as $iRow => $aRowData) {
set_time_limit(intval($iLoopTimeLimit));
// Stop if not the good number of cols in $aRowData
if(count($aRowData) != $iNBFields){
$aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::Format('UI:CSVReport-Row-Issue-NbField',count($aRowData),$iNBFields) );
continue;
}
if (isset($aResult[$iRow]["__STATUS__"])) {
// An issue at the earlier steps - skip the rest
continue;
@@ -1362,11 +1348,7 @@ class BulkChange
{
if (!array_key_exists($iCol, $aResult[$iRow]))
{
if(isset($aRowData[$iCol])) {
$aResult[$iRow][$iCol] = new CellStatus_Void($aRowData[$iCol]);
} else {
$aResult[$iRow][$iCol] = new CellStatus_Issue('', null, Dict::S('UI:CSVReport-Value-Issue-NoValue'));
}
$aResult[$iRow][$iCol] = new CellStatus_Void($aRowData[$iCol]);
}
}
foreach($this->m_aExtKeys as $sAttCode => $aForeignAtts)
@@ -1380,11 +1362,7 @@ class BulkChange
if (!array_key_exists($iCol, $aResult[$iRow]))
{
// The foreign attribute is one of our reconciliation key
if(isset($aRowData[$iCol])) {
$aResult[$iRow][$iCol] = new CellStatus_Void($aRowData[$iCol]);
} else {
$aResult[$iRow][$iCol] = new CellStatus_Issue('', null, 'UI:CSVReport-Value-Issue-NoValue');
}
$aResult[$iRow][$iCol] = new CellStatus_Void($aRowData[$iCol]);
}
}
}

View File

@@ -70,7 +70,7 @@ class BulkExportResult extends DBObject
);
MetaModel::Init_Params($aParams);
MetaModel::Init_AddAttribute(new AttributeDateTime("created", array("allowed_values"=>null, "sql"=>"created", "default_value"=>"NOW()", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("created", array("allowed_values"=>null, "sql"=>"created", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeInteger("user_id", array("allowed_values"=>null, "sql"=>"user_id", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeInteger("chunk_size", array("allowed_values"=>null, "sql"=>"chunk_size", "default_value"=>0, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("format", array("allowed_values"=>null, "sql"=>"format", "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array())));

View File

@@ -33,7 +33,7 @@ class CMDBChange extends DBObject
);
MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>"NOW()", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalKey("user_id", array("allowed_values"=>null, "sql"=>"user_id", "targetclass"=>"User", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeEnum("origin", array("allowed_values"=>new ValueSetEnum(implode(',', [CMDBChangeOrigin::INTERACTIVE, CMDBChangeOrigin::CSV_INTERACTIVE, CMDBChangeOrigin::CSV_IMPORT, CMDBChangeOrigin::WEBSERVICE_SOAP, CMDBChangeOrigin::WEBSERVICE_REST, CMDBChangeOrigin::SYNCHRO_DATA_SOURCE, CMDBChangeOrigin::EMAIL_PROCESSING, CMDBChangeOrigin::CUSTOM_EXTENSION])), "sql"=>"origin", "default_value"=>CMDBChangeOrigin::INTERACTIVE, "is_null_allowed"=>true, "depends_on"=>array())));

View File

@@ -1436,14 +1436,6 @@ class Config
'quick_create.max_history_results' => [
'type' => 'integer',
'description' => 'Max. number of elements in the history',
'default' => 5,
'value' => 5,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'quick_create.max_popular_results' => [
'type' => 'integer',
'description' => 'Max. number of elements in the popular classes section',
'default' => 10,
'value' => 10,
'source_of_value' => '',

View File

@@ -355,30 +355,14 @@
}
}
try {
if ($bIsAsync === true) {
AsyncSendNewsroom::AddToQueue($this->GetKey(), $oTrigger->GetKey(), $aRecipientsIds, $sMessage, $sTitle, $sUrl, $iObjectId, $sObjectClass);
} else {
foreach ($aRecipientsIds as $iRecipientId) {
$oEvent = Combodo\iTop\Service\Notification\Event\EventNotificationNewsroomService::MakeEventFromAction($this, $iRecipientId, $oTrigger->GetKey(), $sMessage, $sTitle, $sUrl, $iObjectId, $sObjectClass);
$oEvent->DBInsertNoReload();
}
}
} catch (CoreCannotSaveObjectException $e) {
ExceptionLog::LogException($e);
foreach($aRecipientsIds as $iRecipientId) {
$oEvent = Combodo\iTop\Service\Notification\Event\EventNotificationNewsroomService::MakeEventFromAction($this,
$iRecipientId,
$oTrigger->GetKey(),
Dict::S('Core:EventNotificationNewsroom:ErrorOnDBInsert'),
Dict::S('Core:EventNotificationNewsroom:ErrorNotificationNotSent'),
$sUrl,
$iObjectId,
$sObjectClass
);
$oEvent->DBInsertNoReload();
}
}
if ($bIsAsync === true) {
AsyncSendNewsroom::AddToQueue($this->GetKey(), $oTrigger->GetKey(), $aRecipientsIds, $sMessage, $sTitle, $sUrl, $iObjectId, $sObjectClass);
} else {
foreach ($aRecipientsIds as $iRecipientId) {
$oEvent = Combodo\iTop\Service\Notification\Event\EventNotificationNewsroomService::MakeEventFromAction($this, $iRecipientId, $oTrigger->GetKey(), $sMessage, $sTitle, $sUrl, $iObjectId, $sObjectClass);
$oEvent->DBInsertNoReload();
}
}
$this->SetNotificationLanguage($sPreviousLanguage, $aPreviousPluginProperties['language_code'] ?? null);
}
@@ -866,18 +850,6 @@
<field id="language" xsi:type="AttributeApplicationLanguage"/>
</fields>
</class>
<class id="Event" _delta="define">
<!-- Generated by toolkit/export-class-to-meta.php -->
<parent>DBObject</parent>
<properties>
<category>core/cmdb,view_in_gui</category>
</properties>
<fields>
<field id="message" xsi:type="AttributeText"/>
<field id="date" xsi:type="AttributeDateTime"/>
<field id="userinfo" xsi:type="AttributeString"/>
</fields>
</class>
<class id="EventNotification" _delta="define">
<!-- Generated by toolkit/export-class-to-meta.php -->
<parent>Event</parent>
@@ -1024,12 +996,6 @@
<type>string</type>
<default/>
</property>
<property id="class_exclusion_list">
<php_param>class_exclusion_list</php_param>
<mandatory>false</mandatory>
<type>string</type>
<default/>
</property>
<property id="min_up">
<php_param>min_up</php_param>
<mandatory>true</mandatory>

View File

@@ -212,8 +212,6 @@ abstract class DBObject implements iDisplay
private $aEventListeners = [];
private array $aAllowedTransitions = [];
private ?string $sStimulusBeingApplied = null;
/**
* DBObject constructor.
*
@@ -760,10 +758,10 @@ abstract class DBObject implements iDisplay
*/
public function SetTrim($sAttCode, $sValue)
{
if (!$this->StringFitsInField($sAttCode, $sValue)) {
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
$iMaxSize = $oAttDef->GetMaxSize();
$sLength = mb_strlen($sValue);
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
$iMaxSize = $oAttDef->GetMaxSize();
$sLength = mb_strlen($sValue);
if ($iMaxSize && ($sLength > $iMaxSize)) {
$sMessage = " -truncated ($sLength chars)";
$sValue = mb_substr($sValue, 0, $iMaxSize - mb_strlen($sMessage)).$sMessage;
}
@@ -818,24 +816,6 @@ abstract class DBObject implements iDisplay
$oKPI->ComputeStatsForExtension($this, 'AfterDelete');
}
/**
* @param string $sAttCode
* @param string $sValue
*
* @return bool
* @throws \Exception
*
* @Since 3.2.2
*/
public function StringFitsInField(string $sAttCode, string $sValue): bool
{
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
$iMaxSize = $oAttDef->GetMaxSize();
$sLength = mb_strlen($sValue);
return !($iMaxSize && ($sLength > $iMaxSize));
}
/**
* Compute (and optionally start) the StopWatches deadlines
*
@@ -1226,7 +1206,7 @@ abstract class DBObject implements iDisplay
if ($aCallInfo["function"] != "ComputeValues") continue;
return; //skip!
}
$this->FireEventComputeValues($this->sStimulusBeingApplied);
$this->FireEventComputeValues();
$oKPI = new ExecutionKPI();
$this->ComputeValues();
$oKPI->ComputeStatsForExtension($this, 'ComputeValues');
@@ -2150,7 +2130,7 @@ abstract class DBObject implements iDisplay
return "Bad type";
}
elseif ($oAtt instanceof AttributeSet)
elseif (($oAtt instanceof AttributeClassAttCodeSet) || ($oAtt instanceof AttributeEnumSet))
{
if (is_string($toCheck))
{
@@ -2689,7 +2669,7 @@ abstract class DBObject implements iDisplay
// Ultimate check - ensure DB integrity
$this->SetReadOnly('No modification allowed during CheckToCreate');
$this->FireEventCheckToWrite($this->sStimulusBeingApplied);
$this->FireEventCheckToWrite();
$this->SetReadWrite();
$oKPI = new ExecutionKPI();
@@ -2885,14 +2865,6 @@ abstract class DBObject implements iDisplay
protected function ListChangedValues(array $aProposal)
{
$aDelta = array();
$sClass = get_class($this);
if (MetaModel::HasLifecycle($sClass) && utils::IsNotNullOrEmptyString($this->sStimulusBeingApplied)) {
$sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
if (!in_array($sStateAttCode, $aProposal)) {
// Same state but the transition was asked, act as if the state was changed
$aDelta[$sStateAttCode] = $this->m_aCurrValues[$sStateAttCode];
}
}
foreach ($aProposal as $sAtt => $proposedValue)
{
if (!array_key_exists($sAtt, $this->m_aOrigValues))
@@ -3426,7 +3398,7 @@ abstract class DBObject implements iDisplay
$this->OnInsert();
$oKPI->ComputeStatsForExtension($this, 'OnInsert');
$this->FireEventBeforeWrite(null);
$this->FireEventBeforeWrite();
// If not automatically computed, then check that the key is given by the caller
if (!MetaModel::IsAutoIncrementKey($sRootClass)) {
@@ -3561,7 +3533,7 @@ abstract class DBObject implements iDisplay
*/
protected function PostInsertActions(): void
{
$this->FireEventAfterWrite([], true, null);
$this->FireEventAfterWrite([], true);
$oKPI = new ExecutionKPI();
$this->AfterInsert();
$oKPI->ComputeStatsForExtension($this, 'AfterInsert');
@@ -3642,13 +3614,13 @@ abstract class DBObject implements iDisplay
*/
public function DBUpdate()
{
$this->LogCRUDEnter(__METHOD__);
if (!MetaModel::StartReentranceProtection($this)) {
$this->LogCRUDExit(__METHOD__, 'Rejected (reentrance)');
return false;
}
$this->LogCRUDEnter(__METHOD__);
if (!$this->m_bIsInDB)
{
throw new CoreException("DBUpdate: could not update a newly created object, please call DBInsert instead");
@@ -3669,7 +3641,7 @@ abstract class DBObject implements iDisplay
$this->OnUpdate();
$oKPI->ComputeStatsForExtension($this, 'OnUpdate');
$this->FireEventBeforeWrite($this->sStimulusBeingApplied);
$this->FireEventBeforeWrite();
// Freeze the changes at this point
$this->InitPreviousValuesForUpdatedAttributes();
@@ -3837,7 +3809,7 @@ abstract class DBObject implements iDisplay
}
try {
$this->PostUpdateActions($this->m_aPreviousValuesForUpdatedAttributes, $sClass);
$this->PostUpdateActions($aChanges, $sClass);
}
catch (Exception $e) {
$this->LogCRUDExit(__METHOD__, 'Error: '.$e->getMessage());
@@ -3880,9 +3852,7 @@ abstract class DBObject implements iDisplay
*/
protected function PostUpdateActions(array $aChanges): void
{
$sStimulusBeingApplied = $this->sStimulusBeingApplied;
$this->sStimulusBeingApplied = null;
$this->FireEventAfterWrite($aChanges, false, $sStimulusBeingApplied);
$this->FireEventAfterWrite($aChanges, false);
$oKPI = new ExecutionKPI();
$this->AfterUpdate();
$oKPI->ComputeStatsForExtension($this, 'AfterUpdate');
@@ -3894,37 +3864,39 @@ abstract class DBObject implements iDisplay
$this->ActivateOnObjectUpdateTriggersForTargetObjects();
$sClass = get_class($this);
if (utils::IsNotNullOrEmptyString($sStimulusBeingApplied))
if (MetaModel::HasLifecycle($sClass))
{
$sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
$sPreviousState = $this->m_aPreviousValuesForUpdatedAttributes[$sStateAttCode];
// Change state triggers...
$aParams = array(
'class_list' => MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL),
'previous_state' => $sPreviousState,
'new_state' => $this->Get($sStateAttCode),
);
$oSet = new DBObjectSet(DBObjectSearch::FromOQL('SELECT TriggerOnStateLeave AS t WHERE t.target_class IN (:class_list) AND t.state=:previous_state'), array(), $aParams);
while ($oTrigger = $oSet->Fetch()) {
/** @var \TriggerOnStateLeave $oTrigger */
try {
$oTrigger->DoActivate($this->ToArgs('this'));
if (isset($this->m_aPreviousValuesForUpdatedAttributes[$sStateAttCode])) {
$sPreviousState = $this->m_aPreviousValuesForUpdatedAttributes[$sStateAttCode];
// Change state triggers...
$aParams = array(
'class_list' => MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL),
'previous_state' => $sPreviousState,
'new_state' => $this->Get($sStateAttCode),
);
$oSet = new DBObjectSet(DBObjectSearch::FromOQL('SELECT TriggerOnStateLeave AS t WHERE t.target_class IN (:class_list) AND t.state=:previous_state'), array(), $aParams);
while ($oTrigger = $oSet->Fetch()) {
/** @var \TriggerOnStateLeave $oTrigger */
try {
$oTrigger->DoActivate($this->ToArgs('this'));
}
catch (Exception $e) {
$oTrigger->LogException($e, $this);
utils::EnrichRaisedException($oTrigger, $e);
}
}
catch (Exception $e) {
$oTrigger->LogException($e, $this);
utils::EnrichRaisedException($oTrigger, $e);
}
}
$oSet = new DBObjectSet(DBObjectSearch::FromOQL('SELECT TriggerOnStateEnter AS t WHERE t.target_class IN (:class_list) AND t.state=:new_state'), array(), $aParams);
while ($oTrigger = $oSet->Fetch()) {
/** @var \TriggerOnStateEnter $oTrigger */
try {
$oTrigger->DoActivate($this->ToArgs('this'));
}
catch (Exception $e) {
$oTrigger->LogException($e, $this);
utils::EnrichRaisedException($oTrigger, $e);
$oSet = new DBObjectSet(DBObjectSearch::FromOQL('SELECT TriggerOnStateEnter AS t WHERE t.target_class IN (:class_list) AND t.state=:new_state'), array(), $aParams);
while ($oTrigger = $oSet->Fetch()) {
/** @var \TriggerOnStateEnter $oTrigger */
try {
$oTrigger->DoActivate($this->ToArgs('this'));
}
catch (Exception $e) {
$oTrigger->LogException($e, $this);
utils::EnrichRaisedException($oTrigger, $e);
}
}
}
}
@@ -4052,7 +4024,7 @@ abstract class DBObject implements iDisplay
foreach ($aUpdatedLogAttCodes as $sAttCode) {
/** @var \ormCaseLog $oUpdatedCaseLog */
$oUpdatedCaseLog = $this->Get($sAttCode);
$aMentionedObjects = array_merge_recursive($aMentionedObjects, utils::GetMentionedObjectsFromText($oUpdatedCaseLog->GetModifiedEntry(ormCaseLog::ENUM_FORMAT_HTML)));
$aMentionedObjects = array_merge_recursive($aMentionedObjects, utils::GetMentionedObjectsFromText($oUpdatedCaseLog->GetModifiedEntry()));
}
// 3 - Trigger for those objects
@@ -4529,8 +4501,6 @@ abstract class DBObject implements iDisplay
*/
public function ApplyStimulus($sStimulusCode, $bDoNotWrite = false)
{
$this->LogCRUDEnter(__METHOD__, "Code: $sStimulusCode");
$sClass = get_class($this);
if (!MetaModel::HasLifecycle($sClass))
{
@@ -4557,8 +4527,6 @@ abstract class DBObject implements iDisplay
} else {
$aBackupValues[$sAttCode] = $value;
}
} else {
$aBackupValues[$sAttCode] = $oAttDef->GetNullValue();
}
}
@@ -4566,6 +4534,7 @@ abstract class DBObject implements iDisplay
// Change the state before proceeding to the actions, this is necessary because an action might
// trigger another stimuli (alternative: push the stimuli into a queue)
$sPreviousState = $this->Get($sStateAttCode);
$sNewState = $aTransitionDef['target_state'];
$this->Set($sStateAttCode, $sNewState);
@@ -4573,71 +4542,67 @@ abstract class DBObject implements iDisplay
// array('target_state'=>..., 'actions'=>array of handlers procs, 'user_restriction'=>TBD
$bSuccess = true;
// Prevent current object from being updated by the actions
$this->AddCurrentObjectInCrudStack('APPLY_STIMULUS');
$bIsNewlyProtected = MetaModel::StartReentranceProtection($this);
try {
foreach ($aTransitionDef['actions'] as $actionHandler) {
if (is_string($actionHandler)) {
// Old (pre-2.1.0 modules) action definition without any parameter
$aActionCallSpec = array($this, $actionHandler);
$sActionDesc = $sClass.'::'.$actionHandler;
$sActionDesc = '';
foreach ($aTransitionDef['actions'] as $actionHandler)
{
if (is_string($actionHandler))
{
// Old (pre-2.1.0 modules) action definition without any parameter
$aActionCallSpec = array($this, $actionHandler);
$sActionDesc = $sClass.'::'.$actionHandler;
if (!is_callable($aActionCallSpec)) {
throw new CoreException("Unable to call action: $sClass::$actionHandler");
}
$bRet = call_user_func($aActionCallSpec, $sStimulusCode);
} else // if (is_array($actionHandler))
if (!is_callable($aActionCallSpec))
{
// New syntax: 'verb' and typed parameters
$sAction = $actionHandler['verb'];
$sActionDesc = "$sClass::$sAction";
$aParams = array();
foreach ($actionHandler['params'] as $aDefinition) {
$sParamType = array_key_exists('type', $aDefinition) ? $aDefinition['type'] : 'string';
switch ($sParamType) {
case 'int':
$value = (int)$aDefinition['value'];
break;
throw new CoreException("Unable to call action: $sClass::$actionHandler");
}
$bRet = call_user_func($aActionCallSpec, $sStimulusCode);
}
else // if (is_array($actionHandler))
{
// New syntax: 'verb' and typed parameters
$sAction = $actionHandler['verb'];
$sActionDesc = "$sClass::$sAction";
$aParams = array();
foreach($actionHandler['params'] as $aDefinition)
{
$sParamType = array_key_exists('type', $aDefinition) ? $aDefinition['type'] : 'string';
switch($sParamType)
{
case 'int':
$value = (int)$aDefinition['value'];
break;
case 'float':
$value = (float)$aDefinition['value'];
break;
case 'float':
$value = (float)$aDefinition['value'];
break;
case 'bool':
$value = (bool)$aDefinition['value'];
break;
case 'bool':
$value = (bool)$aDefinition['value'];
break;
case 'reference':
$value = ${$aDefinition['value']};
break;
case 'reference':
$value = ${$aDefinition['value']};
break;
case 'string':
default:
$value = (string)$aDefinition['value'];
}
$aParams[] = $value;
case 'string':
default:
$value = (string)$aDefinition['value'];
}
$aCallSpec = array($this, $sAction);
$bRet = call_user_func_array($aCallSpec, $aParams);
}
// if one call fails, the whole is considered as failed
// (in case there is no returned value, null is obtained and means "ok")
if ($bRet === false) {
IssueLog::Info("Lifecycle action $sActionDesc returned false on object #$sClass:".$this->GetKey());
$bSuccess = false;
$aParams[] = $value;
}
$aCallSpec = array($this, $sAction);
$bRet = call_user_func_array($aCallSpec, $aParams);
}
} finally {
if ($bIsNewlyProtected) {
// Stops protection only if the object was not already protected
MetaModel::StopReentranceProtection($this);
// if one call fails, the whole is considered as failed
// (in case there is no returned value, null is obtained and means "ok")
if ($bRet === false)
{
IssueLog::Info("Lifecycle action $sActionDesc returned false on object #$sClass:".$this->GetKey());
$bSuccess = false;
}
$this->RemoveCurrentObjectInCrudStack();
}
if ($bSuccess)
{
$this->sStimulusBeingApplied = $sStimulusCode;
// Stop watches
foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
{
@@ -4666,7 +4631,6 @@ abstract class DBObject implements iDisplay
$this->m_aCurrValues[$sAttCode] = $aBackupValues[$sAttCode];
}
}
$this->LogCRUDExit(__METHOD__, 'Current State: '.$this->Get($sStateAttCode));
return $bSuccess;
}
@@ -6653,7 +6617,7 @@ abstract class DBObject implements iDisplay
* @return void
* @since 3.1.0
*/
protected function FireEventCheckToWrite(?string $sStimulusBeingApplied): void
protected function FireEventCheckToWrite(): void
{
}
@@ -6661,7 +6625,7 @@ abstract class DBObject implements iDisplay
* @return void
* @since 3.1.0
*/
protected function FireEventBeforeWrite(?string $sStimulusBeingApplied)
protected function FireEventBeforeWrite()
{
}
@@ -6671,7 +6635,7 @@ abstract class DBObject implements iDisplay
* @return void
* @since 3.1.0
*/
protected function FireEventAfterWrite(array $aChanges, bool $bIsNew, ?string $sStimulusBeingApplied): void
protected function FireEventAfterWrite(array $aChanges, bool $bIsNew): void
{
}
@@ -6709,7 +6673,7 @@ abstract class DBObject implements iDisplay
* @return void
* @since 3.1.0
*/
protected function FireEventComputeValues(?string $sStimulusBeingApplied): void
protected function FireEventComputeValues(): void
{
}
@@ -6751,13 +6715,12 @@ abstract class DBObject implements iDisplay
$oRootClass = MetaModel::GetRootClass($sClass);
foreach (self::$m_aCrudStack as $aCrudStackEntry) {
if (($oRootClass === $aCrudStackEntry['class']) && ($sConvertedId === $aCrudStackEntry['id'])) {
IssueLog::Trace('CRUD '.__METHOD__." $sClass:$sId IS in CRUD Stack", LogChannels::DM_CRUD);
if (($oRootClass === $aCrudStackEntry['class'])
&& ($sConvertedId === $aCrudStackEntry['id'])) {
return true;
}
}
IssueLog::Trace('CRUD '.__METHOD__." $sClass:$sId NOT in CRUD Stack", LogChannels::DM_CRUD);
return false;
}
@@ -6775,12 +6738,10 @@ abstract class DBObject implements iDisplay
$sRootClass = MetaModel::GetRootClass($sClass);
foreach (self::$m_aCrudStack as $aCrudStackEntry) {
if ($sRootClass === $aCrudStackEntry['class']) {
IssueLog::Trace("CRUD ".__METHOD__." $sClass IS in CRUD Stack", LogChannels::DM_CRUD);
return true;
}
}
IssueLog::Trace('CRUD '.__METHOD__." $sClass NOT in CRUD Stack", LogChannels::DM_CRUD);
return false;
}
@@ -6790,20 +6751,17 @@ abstract class DBObject implements iDisplay
* @param string $sCrudType
*
* @return void
* @throws \CoreException
* @since 3.1.0 N°5609
*/
private function AddCurrentObjectInCrudStack(string $sCrudType): void
{
$this->LogCRUDDebug(__METHOD__);
$sRootClass = MetaModel::GetRootClass(get_class($this));
$sKey = (string)$this->GetKey();
self::$m_aCrudStack[] = [
'type' => $sCrudType,
'class' => $sRootClass,
'id' => $sKey, // GetKey() doesn't have type hinting, so forcing type to avoid getting an int
'id' => (string)$this->GetKey(), // GetKey() doesn't have type hinting, so forcing type to avoid getting an int
];
$iCount = count(self::$m_aCrudStack);
$this->LogCRUDDebug(__METHOD__, "$sCrudType $sRootClass:$sKey count $iCount");
}
/**
@@ -6815,15 +6773,10 @@ abstract class DBObject implements iDisplay
*/
private function UpdateCurrentObjectInCrudStack(): void
{
$this->LogCRUDDebug(__METHOD__);
$aCurrentCrudStack = array_pop(self::$m_aCrudStack);
$sOldId = $aCurrentCrudStack['id'];
$sNewId = (string)$this->GetKey();
$aCurrentCrudStack['id'] = $sNewId;
$aCurrentCrudStack['id'] = (string)$this->GetKey();
self::$m_aCrudStack[] = $aCurrentCrudStack;
$sClass = $aCurrentCrudStack['class'];
$sType = $aCurrentCrudStack['type'];
$iCount = count(self::$m_aCrudStack);
$this->LogCRUDDebug(__METHOD__, "$sType $sClass:$sOldId => $sClass:$sNewId count $iCount");
}
/**
@@ -6835,11 +6788,7 @@ abstract class DBObject implements iDisplay
private function RemoveCurrentObjectInCrudStack(): void
{
$aRemoved = array_pop(self::$m_aCrudStack);
$sType = $aRemoved['type'];
$sClass = $aRemoved['class'];
$sId = $aRemoved['id'];
$iCount = count(self::$m_aCrudStack);
$this->LogCRUDDebug(__METHOD__, "$sType $sClass:$sId count $iCount");
$this->LogCRUDDebug(__METHOD__, $aRemoved['class'].':'.$aRemoved['id']);
}
/**
@@ -6856,53 +6805,37 @@ abstract class DBObject implements iDisplay
protected function LogCRUDEnter($sFunction, $sComment = '')
{
$sClass = get_class($this);
if (utils::StartsWith($sClass, 'CMDBChange')) {
return;
}
$sKey = $this->GetKey();
$sUUID = $this->m_sObjectUniqId;
$sPadding = str_pad('', count(self::$m_aCrudStack), '-');
IssueLog::Debug("CRUD +$sPadding> $sFunction $sClass:$sKey ($sUUID) $sComment", LogChannels::DM_CRUD);
IssueLog::Debug("CRUD +$sPadding> $sFunction $sClass:$sKey $sComment", LogChannels::DM_CRUD);
}
protected function LogCRUDExit($sFunction, $sComment = '')
{
$sClass = get_class($this);
if (utils::StartsWith($sClass, 'CMDBChange')) {
return;
}
$sKey = $this->GetKey();
$sUUID = $this->m_sObjectUniqId;
$sPadding = str_pad('', count(self::$m_aCrudStack), '-');
if (strlen($sComment) === 0) {
IssueLog::Trace("CRUD <$sPadding+ $sFunction $sClass:$sKey", LogChannels::DM_CRUD);
} else {
IssueLog::Debug("CRUD <$sPadding+ $sFunction $sClass:$sKey ($sUUID) $sComment", LogChannels::DM_CRUD);
IssueLog::Debug("CRUD <$sPadding+ $sFunction $sClass:$sKey $sComment", LogChannels::DM_CRUD);
}
}
protected function LogCRUDDebug($sFunction, $sComment = '')
{
$sClass = get_class($this);
if (utils::StartsWith($sClass, 'CMDBChange')) {
return;
}
$sKey = $this->GetKey();
$sUUID = $this->m_sObjectUniqId;
$sPadding = str_pad('', count(self::$m_aCrudStack), '-');
IssueLog::Debug("CRUD --$sPadding $sFunction $sClass:$sKey ($sUUID) $sComment", LogChannels::DM_CRUD);
IssueLog::Debug("CRUD --$sPadding $sFunction $sClass:$sKey $sComment", LogChannels::DM_CRUD);
}
protected function LogCRUDError($sFunction, $sComment = '')
{
$sClass = get_class($this);
if (utils::StartsWith($sClass, 'CMDBChange')) {
return;
}
$sKey = $this->GetKey();
$sUUID = $this->m_sObjectUniqId;
$sPadding = str_pad('', count(self::$m_aCrudStack), '!');
IssueLog::Error("CRUD !!$sPadding Error $sFunction $sClass:$sKey ($sUUID) $sComment", LogChannels::DM_CRUD);
IssueLog::Error("CRUD !!$sPadding Error $sFunction $sClass:$sKey $sComment", LogChannels::DM_CRUD);
}
/**

View File

@@ -51,7 +51,7 @@ class DBProperty extends DBObject
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("value", array("allowed_values"=>null, "sql"=>"value", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("change_date", array("allowed_values"=>null, "sql"=>"change_date", "default_value"=>"NOW()", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("change_date", array("allowed_values"=>null, "sql"=>"change_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("change_comment", array("allowed_values"=>null, "sql"=>"change_comment", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
}

View File

@@ -39,7 +39,7 @@ class Event extends DBObject implements iDisplay
MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeText("message", array("allowed_values"=>null, "sql"=>"message", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>"NOW()", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
// MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));

View File

@@ -278,7 +278,7 @@ class HTMLDOMSanitizer extends DOMSanitizer
protected static $aTagsWhiteList = array(
'html' => array(),
'body' => array(),
'a' => array('href', 'name', 'style', 'class', 'target', 'title', 'data-role', 'data-object-class', 'data-object-id', 'data-object-key'),
'a' => array('href', 'name', 'style', 'class', 'target', 'title', 'data-role', 'data-object-class', 'data-object-id'),
'p' => array('style', 'class'),
'blockquote' => array('style', 'class'),
'br' => array(),
@@ -354,8 +354,6 @@ class HTMLDOMSanitizer extends DOMSanitizer
'font-style',
'height',
'margin',
'margin-left',
'margin-right',
'padding',
'text-align',
'vertical-align',

View File

@@ -54,7 +54,7 @@ class InlineImage extends DBObject
);
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeDateTime("expire", array("allowed_values" => null, "sql" => 'expire', "default_value" => 'DATE_ADD(NOW(), INTERVAL 1 DAY)', "is_null_allowed" => false, "depends_on" => array(), "always_load_in_tables" => false)));
MetaModel::Init_AddAttribute(new AttributeDateTime("expire", array("allowed_values"=>null, "sql"=>'expire', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array(), "always_load_in_tables"=>false)));
MetaModel::Init_AddAttribute(new AttributeString("temp_id", array("allowed_values"=>null, "sql"=>'temp_id', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false)));
MetaModel::Init_AddAttribute(new AttributeString("item_class", array("allowed_values"=>null, "sql"=>'item_class', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array(), "always_load_in_tables"=>false)));
MetaModel::Init_AddAttribute(new AttributeObjectKey("item_id", array("class_attcode"=>'item_class', "allowed_values"=>null, "sql"=>'item_id', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false)));

View File

@@ -7112,7 +7112,7 @@ abstract class MetaModel
if ($iKey < 0) {
return "$sTargetClass: $iKey (invalid value)";
}
$oObj = self::GetObject($sTargetClass, $iKey, false);
$oObj = self::GetObject($sTargetClass, $iKey, false);
if (is_null($oObj)) {
// Whatever we are looking for, the root class is the key to search for
$sRootClass = self::GetRootClass($sTargetClass);
@@ -7532,41 +7532,8 @@ abstract class MetaModel
return $aEntries;
}
public static function ResetAllCaches($sEnvironment = null)
{
if (is_null($sEnvironment)) {
$sEnvironment = MetaModel::GetEnvironment();
}
$sEnvironmentId = md5(APPROOT).'-'.$sEnvironment;
$sAppIdentity = 'itop-'.$sEnvironmentId;
require_once(APPROOT.'/core/dict.class.inc.php');
Dict::ResetCache($sAppIdentity);
if (function_exists('apc_delete')) {
foreach (self::GetCacheEntries($sEnvironmentId) as $sKey => $aAPCInfo) {
$sAPCKey = $aAPCInfo['info'];
apc_delete($sAPCKey);
}
}
require_once(APPROOT.'core/userrights.class.inc.php');
UserRights::FlushPrivileges();
// Reset the opcache since otherwise the PHP "model" files may still be cached !!
if (function_exists('opcache_reset')) {
// Zend opcode cache
opcache_reset();
}
require_once(APPROOT.'setup/setuputils.class.inc.php');
SetupUtils::rrmdir(utils::GetCachePath($sEnvironment));
}
/**
* @internal
* @param string $sEnvironmentId
* @deprecated 3.2.1
*/
public static function ResetCache($sEnvironmentId = null)
{
@@ -7590,13 +7557,6 @@ abstract class MetaModel
require_once(APPROOT.'core/userrights.class.inc.php');
UserRights::FlushPrivileges();
// Reset the opcache since otherwise the PHP "model" files may still be cached !!
if (function_exists('opcache_reset'))
{
// Zend opcode cache
opcache_reset();
}
}
/**

View File

@@ -575,15 +575,6 @@ class BinaryExpression extends Expression
case 'LIKE':
$sType = 'like';
break;
case 'NOT LIKE':
$sType = 'notlike';
break;
case 'IN':
$sType = 'in';
break;
case 'NOT IN':
$sType = 'notin';
break;
default:
throw new Exception("Operator '$sOperator' not yet supported");
}
@@ -648,26 +639,7 @@ class BinaryExpression extends Expression
case 'like':
$sEscaped = preg_quote($mRight, '/');
$sEscaped = str_replace(array('%', '_', '\\\\.*', '\\\\.'), array('.*', '.', '%', '_'), $sEscaped);
$pregRes = preg_match("/$sEscaped/i", $mLeft);
if ($pregRes === false) {
throw new Exception("Error in regular expression '$sEscaped'");
}
$result = ($pregRes === 1);
break;
case 'notlike':
$sEscaped = preg_quote($mRight, '/');
$sEscaped = str_replace(array('%', '_', '\\\\.*', '\\\\.'), array('.*', '.', '%', '_'), $sEscaped);
$pregRes = preg_match("/$sEscaped/i", $mLeft);
if ($pregRes === false) {
throw new Exception("Error in regular expression '$sEscaped'");
}
$result = ($pregRes !== 1);
break;
case 'in':
$result = in_array($mLeft, $mRight);
break;
case 'notin':
$result = !in_array($mLeft, $mRight);
$result = (int) preg_match("/$sEscaped/i", $mLeft);
break;
}
return $result;
@@ -2278,12 +2250,7 @@ class ListExpression extends Expression
*/
public function Evaluate(array $aArgs)
{
//throw new Exception('list expression not yet supported');
$aResult = [];
foreach ($this->m_aExpressions as $oExpressions) {
$aResult[] = $oExpressions->Evaluate($aArgs);
}
return $aResult;
throw new Exception('list expression not yet supported');
}
/**

File diff suppressed because it is too large Load Diff

View File

@@ -71,24 +71,28 @@ class_list(A) ::= class_list(L) COMA class_name(X). {
where_statement(A) ::= WHERE condition(C). { A = C;}
where_statement(A) ::= . { A = null;}
join_statement(A) ::= join_statement(S) JOIN join_item(J). {
join_statement(A) ::= join_item(J) join_statement(S). {
// insert the join statement on top of the existing list
array_push(S, J);
array_unshift(S, J);
// and return the updated array
A = S;
}
join_statement(A) ::= . { A = [];}
join_statement(A) ::= join_item(J). {
A = Array(J);
}
join_statement(A) ::= . { A = null;}
join_item(A) ::= class_name(X) AS_ALIAS class_name(Y) ON join_condition(C).
join_item(A) ::= JOIN class_name(X) AS_ALIAS class_name(Y) ON join_condition(C).
{
// create an array with one single item
A = new OqlJoinSpec(X, Y, C);
}
join_item(A) ::= class_name(X) ON join_condition(C).
join_item(A) ::= JOIN class_name(X) ON join_condition(C).
{
// create an array with one single item
A = new OqlJoinSpec(X, X, C);
}
join_condition(A) ::= field_id(X) EQ field_id(Y). { A = new BinaryOqlExpression(X, '=', Y); }
join_condition(A) ::= field_id(X) BELOW field_id(Y). { A = new BinaryOqlExpression(X, 'BELOW', Y); }
join_condition(A) ::= field_id(X) BELOW_STRICT field_id(Y). { A = new BinaryOqlExpression(X, 'BELOW_STRICT', Y); }

View File

@@ -36,13 +36,7 @@ class UnknownClassOqlException extends OqlNormalizeException
{
public function __construct($sInput, OqlName $oName, $aExpecting = null)
{
$aAllowedClasses = [];
foreach ($aExpecting as $sClass) {
if (UserRights::IsActionAllowed($sClass, UR_ACTION_READ)) {
$aAllowedClasses[] = $sClass;
}
}
parent::__construct('Unknown class', $sInput, $oName, $aAllowedClasses);
parent::__construct('Unknown class', $sInput, $oName, $aExpecting);
}
public function GetUserFriendlyDescription()

View File

@@ -48,42 +48,6 @@ class ormDocument
* @since 3.1.0
*/
public const DEFAULT_DOWNLOADS_COUNT = 0;
private static $aKnownExtensions = [
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
'pdf' => 'application/pdf',
'doc' => 'application/msword',
'dot' => 'application/msword',
'xls' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint',
'vsd' => 'application/x-visio',
'vdx' => 'application/visio.drawing',
'odt' => 'application/vnd.oasis.opendocument.text',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'zip' => 'application/zip',
'txt' => 'text/plain',
'htm' => 'text/html',
'html' => 'text/html',
'exe' => 'application/octet-stream',
];
public static function GetKnownExtensions(): array
{
return self::$aKnownExtensions;
}
protected $m_data;
protected $m_sMimeType;
@@ -112,36 +76,6 @@ class ormDocument
$this->m_iDownloadsCount = $iDownloadsCount;
}
/**
* @param string $sPath Absolute path of the document to read
*
* @return \ormDocument
* @throws \Exception
*/
public static function FromFile(string $sPath): ormDocument
{
$sPath = utils::RealPath($sPath, APPROOT);
if (false === $sPath) {
throw new Exception("Failed to load the file '$sPath'. The file does not exist or the current process is not allowed to access it.");
}
$sData = @file_get_contents($sPath);
if (false === $sData) {
throw new Exception("Failed to load the file '$sPath'. The file does not exist or the current process is not allowed to access it.");
}
$sExtension = strtolower(pathinfo($sPath, PATHINFO_EXTENSION));
$sFileName = basename($sPath);
$sMimeType = 'text/plain';
if (array_key_exists($sExtension, ormDocument::$aKnownExtensions)) {
$sMimeType = ormDocument::$aKnownExtensions[$sExtension];
} else if (extension_loaded('fileinfo')) {
$fInfo = new finfo(FILEINFO_MIME);
$sMimeType = $fInfo->file($sPath);
}
return new ormDocument($sData, $sMimeType, $sFileName);
}
public function __toString()
{
if($this->IsEmpty()) return '';

View File

@@ -42,8 +42,8 @@ class iTopOwnershipToken extends DBObject
);
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeDateTime("acquired", array("allowed_values"=>null, "sql"=>'acquired', "default_value"=>'NOW()', "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("last_seen", array("allowed_values"=>null, "sql"=>'last_seen', "default_value"=>'NOW()', "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("acquired", array("allowed_values"=>null, "sql"=>'acquired', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("last_seen", array("allowed_values"=>null, "sql"=>'last_seen', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("obj_class", array("allowed_values"=>null, "sql"=>'obj_class', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeInteger("obj_key", array("allowed_values"=>null, "sql"=>'obj_key', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("token", array("allowed_values"=>null, "sql"=>'token', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array())));

View File

@@ -44,8 +44,6 @@ class ObjectResult
* @var string
* @api
*/
use SanitizeTrait;
public $message;
/**
* @var mixed|null
@@ -158,18 +156,6 @@ class ObjectResult
{
$this->fields[$sAttCode] = $this->MakeResultValue($oObject, $sAttCode, $bExtendedOutput);
}
public function SanitizeContent()
{
foreach($this->fields as $sFieldAttCode => $fieldValue) {
try {
$oAttDef = MetaModel::GetAttributeDef($this->class, $sFieldAttCode);
} catch (Exception $e) { // for special cases like ID
continue;
}
$this->SanitizeFieldIfSensitive($this->fields, $sFieldAttCode, $fieldValue, $oAttDef);
}
}
}
@@ -235,16 +221,6 @@ class RestResultWithObjects extends RestResult
$sObjKey = get_class($oObject).'::'.$oObject->GetKey();
$this->objects[$sObjKey] = $oObjRes;
}
public function SanitizeContent()
{
parent::SanitizeContent();
foreach($this->objects as $sObjKey => $oObjRes)
{
$oObjRes->SanitizeContent();
}
}
}
/**
@@ -332,10 +308,9 @@ class RestDelete
*
* @package Core
*/
class CoreServices implements iRestServiceProvider, iRestInputSanitizer
class CoreServices implements iRestServiceProvider
{
use SanitizeTrait;
/**
/**
* Enumerate services delivered by this class
*
* @param string $sVersion The version (e.g. 1.0) supported by the services
@@ -553,18 +528,18 @@ class CoreServices implements iRestServiceProvider, iRestInputSanitizer
}
else
{
if (!$bExtendedOutput && RestUtils::GetOptionalParam($aParams, 'output_fields', '*') != '*')
if (!$bExtendedOutput && RestUtils::GetOptionalParam($aParams, 'output_fields', '*') != '*')
{
$aFields = $aShowFields[$sClass];
//Id is not a valid attribute to optimize
if (in_array('id', $aFields))
if (in_array('id', $aFields))
{
unset($aFields[array_search('id', $aFields)]);
}
$aAttToLoad = array($oObjectSet->GetClassAlias() => $aFields);
$oObjectSet->OptimizeColumnLoad($aAttToLoad);
}
while ($oObject = $oObjectSet->Fetch())
{
$oResult->AddObject(0, '', $oObject, $aShowFields, $bExtendedOutput);
@@ -762,33 +737,6 @@ class CoreServices implements iRestServiceProvider, iRestInputSanitizer
return $oResult;
}
public function SanitizeJsonInput(string $sJsonInput): string
{
$sSanitizedJsonInput = $sJsonInput;
$aJsonData = json_decode($sSanitizedJsonInput, true);
$sOperation = $aJsonData['operation'];
switch ($sOperation) {
case 'core/check_credentials':
if (isset($aJsonData['password'])) {
$aJsonData['password'] = '*****';
}
break;
case 'core/update':
case 'core/create':
default :
$sClass = $aJsonData['class'];
if (isset($aJsonData['fields'])) {
foreach ($aJsonData['fields'] as $sFieldAttCode => $fieldValue) {
$oAttDef = MetaModel::GetAttributeDef($sClass, $sFieldAttCode);
$this->SanitizeFieldIfSensitive($aJsonData['fields'], $sFieldAttCode, $fieldValue, $oAttDef);
}
}
break;
}
return json_encode($aJsonData, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}
/**
* Helper for object deletion
*/
@@ -927,53 +875,3 @@ class CoreServices implements iRestServiceProvider, iRestInputSanitizer
return $iLimit * max(0, $iPage - 1);
}
}
/**
* Sanitizes sensitive fields on a "json ready" representation of a DBObject
* Useful for logging purposes
*/
trait SanitizeTrait
{
/**
* Sanitize a field if it is sensitive.
*
* @param array $fields The fields array
* @param string $sFieldAttCode The attribute code
* @param mixed $oAttDef The attribute definition
* @throws Exception
*/
private function SanitizeFieldIfSensitive(array &$fields, string $sFieldAttCode, $fieldValue, $oAttDef): void
{
// for simple attribute
if ($oAttDef instanceof iAttributeNoGroupBy) { // iAttributeNoGroupBy is equivalent to sensitive attribute
$fields[$sFieldAttCode] = '*****';
return;
}
// for 1-n / n-n relation
if ($oAttDef instanceof AttributeLinkedSet) {
foreach ($fieldValue as $i => $aLnkValues) {
foreach ($aLnkValues as $sLnkAttCode => $sLnkValue) {
$oLnkAttDef = MetaModel::GetAttributeDef($oAttDef->GetLinkedClass(), $sLnkAttCode);
if ($oLnkAttDef instanceof iAttributeNoGroupBy) { // 1-n relation
$fields[$sFieldAttCode][$i][$sLnkAttCode] = '*****';
}
elseif ($oAttDef instanceof AttributeLinkedSetIndirect && $oLnkAttDef instanceof AttributeExternalField) { // for n-n relation
$oExtKeyAttDef = MetaModel::GetAttributeDef($oLnkAttDef->GetTargetClass(), $oLnkAttDef->GetExtAttCode());
if ($oExtKeyAttDef instanceof iAttributeNoGroupBy) {
$fields[$sFieldAttCode][$i][$sLnkAttCode] = '*****';
}
}
}
}
return;
}
// for external attribute
if ($oAttDef instanceof AttributeExternalField) {
$oExtKeyAttDef = MetaModel::GetAttributeDef($oAttDef->GetTargetClass(), $oAttDef->GetExtAttCode());
if ($oExtKeyAttDef instanceof iAttributeNoGroupBy) {
$fields[$sFieldAttCode] = '*****';
}
}
}
}

View File

@@ -17,8 +17,6 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
/**
* A user defined trigger, to customize the application
* A trigger will activate an action
@@ -172,20 +170,19 @@ abstract class TriggerOnObject extends Trigger
{
$aParams = array
(
"category" => "grant_by_profile,core/cmdb",
"key_type" => "autoincrement",
"name_attcode" => "description",
"category" => "grant_by_profile,core/cmdb",
"key_type" => "autoincrement",
"name_attcode" => "description",
"complementary_name_attcode" => ['finalclass', 'complement'],
"state_attcode" => "",
"state_attcode" => "",
"reconc_keys" => ['description'],
"db_table" => "priv_trigger_onobject",
"db_key_field" => "id",
"db_table" => "priv_trigger_onobject",
"db_key_field" => "id",
"db_finalclass_field" => "",
);
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeClass("target_class",
array("class_category" => "bizmodel", "more_values" => "User,UserExternal,UserInternal,UserLDAP,UserLocal", "sql" => "target_class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array(), "class_exclusion_list" => "Attachment")));
MetaModel::Init_AddAttribute(new AttributeClass("target_class", array("class_category" => "bizmodel", "more_values" => "User,UserExternal,UserInternal,UserLDAP,UserLocal", "sql" => "target_class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeOQL("filter", array("allowed_values" => null, "sql" => "filter", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
// Display lists
@@ -273,36 +270,6 @@ abstract class TriggerOnObject extends Trigger
}
}
/**
* if the target class is Attachment, then the trigger is read-only
* @param $sAttCode
* @param $aReasons
* @param $sTargetState
* @return int
* @throws ArchivedObjectException
* @throws CoreException
*/
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState='')
{
// Force the computed field to be read-only, preventing it to be written
if ($this->Get('target_class') == 'Attachment' ) {
return OPT_ATT_READONLY;
}
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
}
public function DisplayBareHeader(WebPage $oPage, $bEditMode = false)
{
$aHeaderBlocks = parent::DisplayBareHeader($oPage, $bEditMode);
if ($this->Get('target_class') == 'Attachment' ) {
$oPage->AddUiBlock(AlertUIBlockFactory::MakeForWarning('', Dict::S('Class:TriggerOnObject:TriggerClassAttachment/ReadOnlyMessage')));
$oPage->add_ready_script("$('#UIMenuModify').hide();");
}
return $aHeaderBlocks;
}
/**
* Activate trigger based on attribute list given instead of changed attributes
*
@@ -562,7 +529,6 @@ class TriggerOnObjectCreate extends TriggerOnObject
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
}
/**

View File

@@ -1921,45 +1921,50 @@ class UserRights
*/
protected static function FindUser($sLogin, $sAuthentication = 'any', $bAllowDisabledUsers = false)
{
if ($sAuthentication === 'any') {
$oUser = self::FindUser($sLogin, 'internal', $bAllowDisabledUsers);
if ($oUser !== null) {
return $oUser;
if ($sAuthentication == 'any')
{
$oUser = self::FindUser($sLogin, 'internal');
if ($oUser == null)
{
$oUser = self::FindUser($sLogin, 'external');
}
}
else
{
if (!isset(self::$m_aCacheUsers))
{
self::$m_aCacheUsers = array('internal' => array(), 'external' => array());
}
return self::FindUser($sLogin, 'external', $bAllowDisabledUsers);
}
if (!isset(self::$m_aCacheUsers[$sAuthentication][$sLogin]))
{
switch($sAuthentication)
{
case 'external':
$sBaseClass = 'UserExternal';
break;
if (!isset(self::$m_aCacheUsers)) {
self::$m_aCacheUsers = [ 'internal' => [], 'external' => [] ];
}
case 'internal':
$sBaseClass = 'UserInternal';
break;
if (! isset(self::$m_aCacheUsers[$sAuthentication]) || ! array_key_exists($sLogin, self::$m_aCacheUsers[$sAuthentication])) {
switch($sAuthentication) {
case 'external':
$sBaseClass = 'UserExternal';
break;
case 'internal':
$sBaseClass = 'UserInternal';
break;
default:
echo "<p>sAuthentication = $sAuthentication</p>\n";
assert(false); // should never happen
default:
echo "<p>sAuthentication = $sAuthentication</p>\n";
assert(false); // should never happen
}
$oSearch = DBObjectSearch::FromOQL("SELECT $sBaseClass WHERE login = :login");
$oSearch->AllowAllData();
if (!$bAllowDisabledUsers)
{
$oSearch->AddCondition('status', 'enabled');
}
$oSet = new DBObjectSet($oSearch, array(), array('login' => $sLogin));
$oUser = $oSet->fetch();
self::$m_aCacheUsers[$sAuthentication][$sLogin] = $oUser;
}
$oSearch = DBObjectSearch::FromOQL("SELECT $sBaseClass WHERE login = :login");
$oSearch->AllowAllData();
if (!$bAllowDisabledUsers) {
$oSearch->AddCondition('status', 'enabled');
}
$oSet = new DBObjectSet($oSearch, array(), array('login' => $sLogin));
$oUser = $oSet->fetch();
self::$m_aCacheUsers[$sAuthentication][$sLogin] = $oUser;
$oUser = self::$m_aCacheUsers[$sAuthentication][$sLogin];
}
return self::$m_aCacheUsers[$sAuthentication][$sLogin];
return $oUser;
}
/**

View File

@@ -1,4 +1,4 @@
/*
/*!
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/

View File

@@ -1,4 +1,4 @@
/*
/*!
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/

View File

@@ -1,4 +1,4 @@
/*
/*!
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/

View File

@@ -1,4 +1,4 @@
/*
/*!
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/

View File

@@ -1,4 +1,4 @@
/*
/*!
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/

View File

@@ -1,4 +1,4 @@
/*
/*!
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/

View File

@@ -99,28 +99,6 @@ $ibo-color-pink-800: $common-color-pink-800 !default;
$ibo-color-pink-900: $common-color-pink-900 !default;
$ibo-color-pink-950: $common-color-pink-950 !default;
$ibo-color-yellow-100: $common-color-yellow-100 !default;
$ibo-color-yellow-200: $common-color-yellow-200 !default;
$ibo-color-yellow-300: $common-color-yellow-300 !default;
$ibo-color-yellow-400: $common-color-yellow-400 !default;
$ibo-color-yellow-500: $common-color-yellow-500 !default;
$ibo-color-yellow-600: $common-color-yellow-600 !default;
$ibo-color-yellow-700: $common-color-yellow-700 !default;
$ibo-color-yellow-800: $common-color-yellow-800 !default;
$ibo-color-yellow-900: $common-color-yellow-900 !default;
$ibo-color-yellow-950: $common-color-yellow-950 !default;
$ibo-color-purple-100: $common-color-purple-100 !default;
$ibo-color-purple-200: $common-color-purple-200 !default;
$ibo-color-purple-300: $common-color-purple-300 !default;
$ibo-color-purple-400: $common-color-purple-400 !default;
$ibo-color-purple-500: $common-color-purple-500 !default;
$ibo-color-purple-600: $common-color-purple-600 !default;
$ibo-color-purple-700: $common-color-purple-700 !default;
$ibo-color-purple-800: $common-color-purple-800 !default;
$ibo-color-purple-900: $common-color-purple-900 !default;
$ibo-color-purple-950: $common-color-purple-950 !default;
$ibo-colors: $common-colors;
/* CSS variables */
@@ -218,26 +196,4 @@ $ibo-colors: $common-colors;
--ibo-color-pink-800: #{$ibo-color-pink-800};
--ibo-color-pink-900: #{$ibo-color-pink-900};
--ibo-color-pink-950: #{$ibo-color-pink-950};
--ibo-color-yellow-100: #{$ibo-color-yellow-100};
--ibo-color-yellow-200: #{$ibo-color-yellow-200};
--ibo-color-yellow-300: #{$ibo-color-yellow-300};
--ibo-color-yellow-400: #{$ibo-color-yellow-400};
--ibo-color-yellow-500: #{$ibo-color-yellow-500};
--ibo-color-yellow-600: #{$ibo-color-yellow-600};
--ibo-color-yellow-700: #{$ibo-color-yellow-700};
--ibo-color-yellow-800: #{$ibo-color-yellow-800};
--ibo-color-yellow-900: #{$ibo-color-yellow-900};
--ibo-color-yellow-950: #{$ibo-color-yellow-950};
--ibo-color-purple-100: #{$ibo-color-purple-100};
--ibo-color-purple-200: #{$ibo-color-purple-200};
--ibo-color-purple-300: #{$ibo-color-purple-300};
--ibo-color-purple-400: #{$ibo-color-purple-400};
--ibo-color-purple-500: #{$ibo-color-purple-500};
--ibo-color-purple-600: #{$ibo-color-purple-600};
--ibo-color-purple-700: #{$ibo-color-purple-700};
--ibo-color-purple-800: #{$ibo-color-purple-800};
--ibo-color-purple-900: #{$ibo-color-purple-900};
--ibo-color-purple-950: #{$ibo-color-purple-950};
}

View File

@@ -1,4 +1,4 @@
/*
/*!
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/

View File

@@ -1,4 +1,4 @@
/*
/*!
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/

View File

@@ -1,4 +1,4 @@
/*
/*!
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/

View File

@@ -1,10 +1,10 @@
/*
/*!
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
/* SCSS variables */
$common-has-description--content: "\1F6C8" !default;
$common-has-description--content: "?" !default;
$common-has-description--padding-left: $common-spacing-200 !default;
$common-has-description--color: $common-color-grey-600 !default;
$common-has-description--font-size: 0.7em !default; /* Font size is em on purpose as we want it to be proportional to its context */

View File

@@ -1,4 +1,4 @@
/*
/*!
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/

View File

@@ -99,26 +99,4 @@ $common-color-pink-800: hsla(322, 60%, 37%, 1) !default;
$common-color-pink-900: hsla(318, 51%, 29%, 1) !default;
$common-color-pink-950: hsla(318, 51%, 21%, 1) !default;
$common-color-yellow-100: hsla(60, 100%, 97.06%, 1) !default;
$common-color-yellow-200: hsla(58.1, 96.92%, 87.25%, 1) !default;
$common-color-yellow-300: hsla(54.69, 91.87%, 75.88%, 1) !default;
$common-color-yellow-400: hsla(51.32, 89.41%, 66.67%, 1) !default;
$common-color-yellow-500: hsla(46.96, 80.9%, 60.98%, 1) !default;
$common-color-yellow-600: hsla(40, 67.2%, 50.98%, 1) !default;
$common-color-yellow-700: hsla(35.53, 71.03%, 41.96%, 1) !default;
$common-color-yellow-800: hsla(31.63, 74.57%, 33.92%, 1) !default;
$common-color-yellow-900: hsla(30, 75.76%, 25.88%, 1) !default;
$common-color-yellow-950: hsla(29, 80%, 17%, 1) !default;
$common-color-purple-100: hsla(251.43, 91.3%, 95.49%, 1) !default;
$common-color-purple-200: hsla(250.5, 95.24%, 91.76%, 1) !default;
$common-color-purple-300: hsla(252.5, 94.74%, 85.1%, 1) !default;
$common-color-purple-400: hsla(255.14, 91.74%, 76.27%, 1) !default;
$common-color-purple-500: hsla(258.31, 89.53%, 66.27%, 1) !default;
$common-color-purple-600: hsla(262.12, 83.26%, 57.84%, 1) !default;
$common-color-purple-700: hsla(263.39, 69.96%, 50.39%, 1) !default;
$common-color-purple-800: hsla(263.36, 69.3%, 42.16%, 1) !default;
$common-color-purple-900: hsla(263.5, 67.42%, 34.9%, 1) !default;
$common-color-purple-950: hsla(263, 71%, 26%, 1) !default;
$common-colors: ('grey', 'blue-grey', 'blue', 'cyan', 'green', 'orange', 'red', 'pink', 'yellow', 'purple', 'primary', 'secondary', 'information', 'success', 'warning', 'danger');
$common-colors: ('grey', 'blue-grey', 'blue', 'cyan', 'green', 'orange', 'red', 'pink', 'primary', 'secondary', 'information', 'success', 'warning', 'danger');

View File

@@ -1,5 +1,4 @@
{
"name": "combodo/authent-cas",
"config" : {
"classmap-authoritative" : true
},

View File

@@ -4,15 +4,15 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "2f342cfe65023402c1e00d88698d52b9",
"content-hash": "d751713988987e9331980363e24189ce",
"packages": [],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {},
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {},
"platform-dev": {},
"plugin-api-version": "2.6.0"
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.1.0"
}

View File

@@ -9,8 +9,8 @@
/**
*
*/
Dict::Add('CS CZ', 'Czech', 'Čeština', array(
Dict::Add('CS CZ', 'Czech', 'Čeština', [
'CAS:Error:UserNotAllowed' => 'Uživatel není oprávněn',
'CAS:Login:SignIn' => 'Přihlásit se prostřednictvím CAS',
'CAS:Login:SignInTooltip' => 'Klikni zde pro příhlášení prostřednictvím CAS serveru',
));
]);

View File

@@ -9,8 +9,8 @@
/**
*
*/
Dict::Add('DA DA', 'Danish', 'Dansk', array(
Dict::Add('DA DA', 'Danish', 'Dansk', [
'CAS:Error:UserNotAllowed' => 'User not allowed~~',
'CAS:Login:SignIn' => 'Sign in with CAS~~',
'CAS:Login:SignInTooltip' => 'Click here to authenticate yourself with the CAS server~~',
));
]);

View File

@@ -9,8 +9,8 @@
/**
*
*/
Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', [
'CAS:Error:UserNotAllowed' => 'Benutzer ist nicht zugelassen',
'CAS:Login:SignIn' => 'Anmeldung mit CAS',
'CAS:Login:SignInTooltip' => 'Hier klicken, um sich am CAS-Server zu authentifizieren',
));
]);

View File

@@ -7,8 +7,8 @@
* @author Miguel Turrubiates <miguel_tf@yahoo.com>
* @notas Utilizar codificación UTF-8 para mostrar acentos y otros caracteres especiales
*/
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
'CAS:Error:UserNotAllowed' => 'Usuario no permitido',
'CAS:Login:SignIn' => 'Iniciar sesión con CAS',
'CAS:Login:SignInTooltip' => 'Click para autenticarse con servidor CAS',
));
]);

View File

@@ -9,8 +9,8 @@
/**
*
*/
Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', [
'CAS:Error:UserNotAllowed' => 'Utilisateur non autorisé',
'CAS:Login:SignIn' => 'S\'identifier avec CAS',
'CAS:Login:SignInTooltip' => 'Cliquer ici pour s\'identifier avec le serveur CAS',
));
]);

View File

@@ -9,8 +9,8 @@
/**
*
*/
Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
'CAS:Error:UserNotAllowed' => 'Nem engedélyezett felhasználó',
'CAS:Login:SignIn' => 'Bejelentkezés CAS szerverrel',
'CAS:Login:SignInTooltip' => 'Kattintson ide az azonosításhoz a CAS szerveren',
));
]);

View File

@@ -9,8 +9,8 @@
/**
*
*/
Dict::Add('IT IT', 'Italian', 'Italiano', array(
Dict::Add('IT IT', 'Italian', 'Italiano', [
'CAS:Error:UserNotAllowed' => 'Utente non autorizzato',
'CAS:Login:SignIn' => 'Accedi con CAS',
'CAS:Login:SignInTooltip' => 'Clicca qui per autenticarti con il server CAS',
));
]);

View File

@@ -9,8 +9,8 @@
/**
*
*/
Dict::Add('JA JP', 'Japanese', '日本語', array(
Dict::Add('JA JP', 'Japanese', '日本語', [
'CAS:Error:UserNotAllowed' => 'User not allowed~~',
'CAS:Login:SignIn' => 'Sign in with CAS~~',
'CAS:Login:SignInTooltip' => 'Click here to authenticate yourself with the CAS server~~',
));
]);

View File

@@ -10,8 +10,8 @@
* @author Jeffrey Bostoen <info@jeffreybostoen.be> (2018 - 2022)
*
*/
Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
'CAS:Error:UserNotAllowed' => 'Gebruiker heeft onvoldoende rechten.',
'CAS:Login:SignIn' => 'Inloggen met CAS',
'CAS:Login:SignInTooltip' => 'Klik hier om aan te melden via de CAS-server',
));
]);

View File

@@ -9,8 +9,8 @@
/**
*
*/
Dict::Add('PL PL', 'Polish', 'Polski', array(
Dict::Add('PL PL', 'Polish', 'Polski', [
'CAS:Error:UserNotAllowed' => 'Użytkownik niedozwolony',
'CAS:Login:SignIn' => 'Zaloguj się za pomocą CAS',
'CAS:Login:SignInTooltip' => 'Kliknij tutaj, aby uwierzytelnić się na serwerze CAS',
));
]);

View File

@@ -9,8 +9,8 @@
/**
*
*/
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
'CAS:Error:UserNotAllowed' => 'Usuário não permitido',
'CAS:Login:SignIn' => 'Autenticar com CAS',
'CAS:Login:SignInTooltip' => 'Clique aqui para se autenticar no servidor CAS',
));
]);

View File

@@ -10,8 +10,8 @@
* @author Vladimir Kunin <v.b.kunin@gmail.com>
*
*/
Dict::Add('RU RU', 'Russian', 'Русский', array(
Dict::Add('RU RU', 'Russian', 'Русский', [
'CAS:Error:UserNotAllowed' => 'Вход не разрешён',
'CAS:Login:SignIn' => 'Вход через CAS',
'CAS:Login:SignInTooltip' => 'Нажмите здесь, чтобы войти через CAS сервер',
));
]);

View File

@@ -9,8 +9,8 @@
/**
*
*/
Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
'CAS:Error:UserNotAllowed' => 'User not allowed~~',
'CAS:Login:SignIn' => 'Sign in with CAS~~',
'CAS:Login:SignInTooltip' => 'Click here to authenticate yourself with the CAS server~~',
));
]);

View File

@@ -9,8 +9,8 @@
/**
*
*/
Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
'CAS:Error:UserNotAllowed' => 'User not allowed~~',
'CAS:Login:SignIn' => 'Sign in with CAS~~',
'CAS:Login:SignInTooltip' => 'Click here to authenticate yourself with the CAS server~~',
));
]);

View File

@@ -4,9 +4,13 @@
*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license https://opensource.org/licenses/AGPL-3.0
*
*/
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
/**
*
*/
Dict::Add('ZH CN', 'Chinese', '简体中文', [
'CAS:Error:UserNotAllowed' => '用户被禁止登录',
'CAS:Login:SignIn' => '使用CAS登录',
'CAS:Login:SignInTooltip' => '点击这里使用CAS服务器认证',
));
]);

View File

@@ -160,7 +160,8 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
private static function InitCASClient()
{
$bCASDebug = Config::Get('cas_debug');
if ($bCASDebug) {
if ($bCASDebug)
{
phpCAS::setLogger(new CASLogger(APPROOT.'log/cas.log'));
}
@@ -170,17 +171,18 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
$iCASPort = Config::Get('cas_port');
$sCASContext = Config::Get('cas_context');
$sServiceBaseURL = Config::Get('service_base_url', self::GetServiceBaseURL());
if (!phpCAS::isInitialized()) {
phpCAS::client($sCASVersion, $sCASHost, $iCASPort, $sCASContext, $sServiceBaseURL, false /* session already started */);
}
phpCAS::client($sCASVersion, $sCASHost, $iCASPort, $sCASContext, $sServiceBaseURL, false /* session already started */);
$sCASCACertPath = Config::Get('cas_server_ca_cert_path');
if (empty($sCASCACertPath)) {
if (empty($sCASCACertPath))
{
// If no certificate authority is provided, do not attempt to validate
// the server's certificate
// THIS SETTING IS NOT RECOMMENDED FOR PRODUCTION.
// VALIDATING THE CAS SERVER IS CRUCIAL TO THE SECURITY OF THE CAS PROTOCOL!
phpCAS::setNoCasServerValidation();
} else {
}
else
{
phpCAS::setCasServerCACert($sCASCACertPath);
}
}

View File

@@ -2,24 +2,6 @@
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
trigger_error(
$err,
E_USER_ERROR
);
}
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit2f342cfe65023402c1e00d88698d52b9::getLoader();
return ComposerAutoloaderInit1878ad96115c3aa0fa5e9fd9807f5db0::getLoader();

View File

@@ -42,37 +42,35 @@ namespace Composer\Autoload;
*/
class ClassLoader
{
/** @var \Closure(string):void */
private static $includeFile;
/** @var string|null */
/** @var ?string */
private $vendorDir;
// PSR-4
/**
* @var array<string, array<string, int>>
* @var array[]
* @psalm-var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array<string, list<string>>
* @var array[]
* @psalm-var array<string, array<int, string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var list<string>
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* List of PSR-0 prefixes
*
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
*
* @var array<string, array<string, list<string>>>
* @var array[]
* @psalm-var array<string, array<string, string[]>>
*/
private $prefixesPsr0 = array();
/**
* @var list<string>
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr0 = array();
@@ -80,7 +78,8 @@ class ClassLoader
private $useIncludePath = false;
/**
* @var array<string, string>
* @var string[]
* @psalm-var array<string, string>
*/
private $classMap = array();
@@ -88,29 +87,29 @@ class ClassLoader
private $classMapAuthoritative = false;
/**
* @var array<string, bool>
* @var bool[]
* @psalm-var array<string, bool>
*/
private $missingClasses = array();
/** @var string|null */
/** @var ?string */
private $apcuPrefix;
/**
* @var array<string, self>
* @var self[]
*/
private static $registeredLoaders = array();
/**
* @param string|null $vendorDir
* @param ?string $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
}
/**
* @return array<string, list<string>>
* @return string[]
*/
public function getPrefixes()
{
@@ -122,7 +121,8 @@ class ClassLoader
}
/**
* @return array<string, list<string>>
* @return array[]
* @psalm-return array<string, array<int, string>>
*/
public function getPrefixesPsr4()
{
@@ -130,7 +130,8 @@ class ClassLoader
}
/**
* @return list<string>
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirs()
{
@@ -138,7 +139,8 @@ class ClassLoader
}
/**
* @return list<string>
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirsPsr4()
{
@@ -146,7 +148,8 @@ class ClassLoader
}
/**
* @return array<string, string> Array of classname => path
* @return string[] Array of classname => path
* @psalm-var array<string, string>
*/
public function getClassMap()
{
@@ -154,7 +157,8 @@ class ClassLoader
}
/**
* @param array<string, string> $classMap Class to filename map
* @param string[] $classMap Class to filename map
* @psalm-param array<string, string> $classMap
*
* @return void
*/
@@ -171,25 +175,24 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
$paths,
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
$paths
(array) $paths
);
}
@@ -198,19 +201,19 @@ class ClassLoader
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = $paths;
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$paths,
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
$paths
(array) $paths
);
}
}
@@ -219,9 +222,9 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
@@ -229,18 +232,17 @@ class ClassLoader
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
$paths,
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
$paths
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
@@ -250,18 +252,18 @@ class ClassLoader
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = $paths;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$paths,
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
$paths
(array) $paths
);
}
}
@@ -270,8 +272,8 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 base directories
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 base directories
*
* @return void
*/
@@ -288,8 +290,8 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
@@ -423,8 +425,7 @@ class ClassLoader
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
$includeFile = self::$includeFile;
$includeFile($file);
includeFile($file);
return true;
}
@@ -475,9 +476,9 @@ class ClassLoader
}
/**
* Returns the currently registered loaders keyed by their corresponding vendor directories.
* Returns the currently registered loaders indexed by their corresponding vendor directories.
*
* @return array<string, self>
* @return self[]
*/
public static function getRegisteredLoaders()
{
@@ -554,26 +555,18 @@ class ClassLoader
return false;
}
/**
* @return void
*/
private static function initializeIncludeClosure()
{
if (self::$includeFile !== null) {
return;
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
*/
self::$includeFile = \Closure::bind(static function($file) {
include $file;
}, null, null);
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
* @private
*/
function includeFile($file)
{
include $file;
}

View File

@@ -21,31 +21,11 @@ use Composer\Semver\VersionParser;
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/
class InstalledVersions
{
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool
*/
private static $installedIsLocalDir;
/**
* @var bool|null
*/
private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
/**
@@ -103,7 +83,7 @@ class InstalledVersions
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
}
}
@@ -124,7 +104,7 @@ class InstalledVersions
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints((string) $constraint);
$constraint = $parser->parseConstraints($constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
@@ -248,7 +228,7 @@ class InstalledVersions
/**
* @return array
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
* @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
*/
public static function getRootPackage()
{
@@ -262,7 +242,7 @@ class InstalledVersions
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
* @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
*/
public static function getRawData()
{
@@ -285,7 +265,7 @@ class InstalledVersions
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
*/
public static function getAllRawData()
{
@@ -308,23 +288,17 @@ class InstalledVersions
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
* @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
*/
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
// when using reload, we disable the duplicate protection to ensure that self::$installed data is
// always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
// so we have to assume it does not, and that may result in duplicate data being returned when listing
// all installed packages for example
self::$installedIsLocalDir = false;
}
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
*/
private static function getInstalled()
{
@@ -333,27 +307,17 @@ class InstalledVersions
}
$installed = array();
$copiedLocalDir = false;
if (self::$canGetVendors) {
$selfDir = strtr(__DIR__, '\\', '/');
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
$vendorDir = strtr($vendorDir, '\\', '/');
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
self::$installedByVendor[$vendorDir] = $required;
$installed[] = $required;
if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
self::$installed = $required;
self::$installedIsLocalDir = true;
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1];
}
}
if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
$copiedLocalDir = true;
}
}
}
@@ -361,17 +325,12 @@ class InstalledVersions
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
self::$installed = require __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
if (self::$installed !== array() && !$copiedLocalDir) {
$installed[] = self::$installed;
}
$installed[] = self::$installed;
return $installed;
}

View File

@@ -2,7 +2,7 @@
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(__DIR__);
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(

View File

@@ -2,7 +2,7 @@
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(__DIR__);
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(

View File

@@ -2,7 +2,7 @@
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(__DIR__);
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(

View File

@@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit2f342cfe65023402c1e00d88698d52b9
class ComposerAutoloaderInit1878ad96115c3aa0fa5e9fd9807f5db0
{
private static $loader;
@@ -22,12 +22,21 @@ class ComposerAutoloaderInit2f342cfe65023402c1e00d88698d52b9
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit2f342cfe65023402c1e00d88698d52b9', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit2f342cfe65023402c1e00d88698d52b9', 'loadClassLoader'));
spl_autoload_register(array('ComposerAutoloaderInit1878ad96115c3aa0fa5e9fd9807f5db0', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
spl_autoload_unregister(array('ComposerAutoloaderInit1878ad96115c3aa0fa5e9fd9807f5db0', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit2f342cfe65023402c1e00d88698d52b9::getInitializer($loader));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit1878ad96115c3aa0fa5e9fd9807f5db0::getInitializer($loader));
} else {
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->setClassMapAuthoritative(true);
$loader->register(true);

View File

@@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInit2f342cfe65023402c1e00d88698d52b9
class ComposerStaticInit1878ad96115c3aa0fa5e9fd9807f5db0
{
public static $prefixLengthsPsr4 = array (
'C' =>
@@ -31,9 +31,9 @@ class ComposerStaticInit2f342cfe65023402c1e00d88698d52b9
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit2f342cfe65023402c1e00d88698d52b9::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit2f342cfe65023402c1e00d88698d52b9::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit2f342cfe65023402c1e00d88698d52b9::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit1878ad96115c3aa0fa5e9fd9807f5db0::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit1878ad96115c3aa0fa5e9fd9807f5db0::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit1878ad96115c3aa0fa5e9fd9807f5db0::$classMap;
}, null, ClassLoader::class);
}

View File

@@ -1,22 +1,22 @@
<?php return array(
'root' => array(
'name' => 'combodo/authent-cas',
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
'reference' => '567bdc4200f5edb335a39c4b48fbd18bacb6cfc7',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => '5a1627632aa2e605996c1c556c60c2a2cddc0a05',
'name' => '__root__',
'dev' => true,
),
'versions' => array(
'combodo/authent-cas' => array(
'__root__' => array(
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
'reference' => '567bdc4200f5edb335a39c4b48fbd18bacb6cfc7',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => '5a1627632aa2e605996c1c556c60c2a2cddc0a05',
'dev_requirement' => false,
),
),

View File

@@ -11,7 +11,7 @@
* @author Daniel Rokos <daniel.rokos@itopportal.cz>
*
*/
Dict::Add('CS CZ', 'Czech', 'Čeština', array(
Dict::Add('CS CZ', 'Czech', 'Čeština', [
'Class:UserExternal' => 'Externí uživatel',
'Class:UserExternal+' => 'Uživatel definovaný mimo '.ITOP_APPLICATION_SHORT,
));
]);

View File

@@ -10,7 +10,7 @@
* @author Erik Bøg <erik@boegmoeller.dk>
*
*/
Dict::Add('DA DA', 'Danish', 'Dansk', array(
Dict::Add('DA DA', 'Danish', 'Dansk', [
'Class:UserExternal' => 'Extern Bruger',
'Class:UserExternal+' => 'Bruger udenfor '.ITOP_APPLICATION_SHORT,
));
]);

View File

@@ -10,7 +10,7 @@
* @author ITOMIG GmbH <martin.raenker@itomig.de>
*
*/
Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', [
'Class:UserExternal' => 'Externer Benutzer',
'Class:UserExternal+' => 'Extern authentifizierter '.ITOP_APPLICATION_SHORT.'-Benutzer',
));
]);

View File

@@ -7,7 +7,7 @@
* @author Miguel Turrubiates <miguel_tf@yahoo.com>
* @notas Utilizar codificación UTF-8 para mostrar acentos y otros caracteres especiales
*/
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
'Class:UserExternal' => 'Usuario externo',
'Class:UserExternal+' => 'Usuario autenticado fuera de '.ITOP_APPLICATION_SHORT,
));
]);

View File

@@ -9,7 +9,7 @@
/**
*
*/
Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', [
'Class:UserExternal' => 'Utilisateur externe à '.ITOP_APPLICATION_SHORT,
'Class:UserExternal+' => 'Utilisateur authentifié à l\'extérieur de '.ITOP_APPLICATION_SHORT,
));
]);

View File

@@ -9,7 +9,7 @@
/**
*
*/
Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
'Class:UserExternal' => 'Külső felhasználó',
'Class:UserExternal+' => '',
));
]);

View File

@@ -9,7 +9,7 @@
/**
*
*/
Dict::Add('IT IT', 'Italian', 'Italiano', array(
Dict::Add('IT IT', 'Italian', 'Italiano', [
'Class:UserExternal' => 'Esterno utente',
'Class:UserExternal+' => 'Utente autenticato al di fuori di '.ITOP_APPLICATION_SHORT,
));
]);

View File

@@ -10,7 +10,7 @@
* @author Hirofumi Kosaka <kosaka@rworks.jp>
*
*/
Dict::Add('JA JP', 'Japanese', '日本語', array(
Dict::Add('JA JP', 'Japanese', '日本語', [
'Class:UserExternal' => '外部ユーザー',
'Class:UserExternal+' => '外部認証ユーザー',
));
]);

View File

@@ -10,7 +10,7 @@
* @author Jeffrey Bostoen <info@jeffreybostoen.be> (2018 - 2022)
*
*/
Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
'Class:UserExternal' => 'Externe gebruiker',
'Class:UserExternal+' => 'Gebruiker aangemeld via externe authenticatie',
));
]);

View File

@@ -9,7 +9,7 @@
/**
*
*/
Dict::Add('PL PL', 'Polish', 'Polski', array(
Dict::Add('PL PL', 'Polish', 'Polski', [
'Class:UserExternal' => 'Użytkownik zewnętrzny',
'Class:UserExternal+' => 'Użytkownik uwierzytelniony poza '.ITOP_APPLICATION_SHORT,
));
]);

View File

@@ -9,7 +9,7 @@
/**
*
*/
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
'Class:UserExternal' => 'Usuário externo',
'Class:UserExternal+' => '',
));
]);

View File

@@ -10,7 +10,7 @@
* @author Vladimir Kunin <v.b.kunin@gmail.com>
*
*/
Dict::Add('RU RU', 'Russian', 'Русский', array(
Dict::Add('RU RU', 'Russian', 'Русский', [
'Class:UserExternal' => 'Внешний пользователь',
'Class:UserExternal+' => 'Пользователь, аутентифицируемый вне '.ITOP_APPLICATION_SHORT,
));
]);

View File

@@ -9,7 +9,7 @@
/**
*
*/
Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
'Class:UserExternal' => 'Externý užívateľ',
'Class:UserExternal+' => 'User authentified outside of '.ITOP_APPLICATION_SHORT.'~~',
));
]);

View File

@@ -10,7 +10,7 @@
* @author Izzet Sirin <izzet.sirin@htr.com.tr>
*
*/
Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
'Class:UserExternal' => 'Harici kullanıcı',
'Class:UserExternal+' => ITOP_APPLICATION_SHORT.' dışında yetki kontrolü yapılan kullanıcı',
));
]);

View File

@@ -4,37 +4,13 @@
*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license https://opensource.org/licenses/AGPL-3.0
*
*
*/
/**
* @author Robert Deng <denglx@gmail.com>
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with iTop. If not, see <http://www.gnu.org/licenses/>
*/
// Dictionnay conventions
// Class:<class_name>
// Class:<class_name>+
// Class:<class_name>/Attribute:<attribute_code>
// Class:<class_name>/Attribute:<attribute_code>+
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
// Class:<class_name>/Stimulus:<stimulus_code>
// Class:<class_name>/Stimulus:<stimulus_code>+
//
// Class: UserExternal
//
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
Dict::Add('ZH CN', 'Chinese', '简体中文', [
'Class:UserExternal' => '外部用户',
'Class:UserExternal+' => '用户在'.ITOP_APPLICATION_SHORT.'外部验证身份',
));
]);

View File

@@ -11,17 +11,8 @@
* @author Daniel Rokos <daniel.rokos@itopportal.cz>
*
*/
Dict::Add('CS CZ', 'Czech', 'Čeština', array(
Dict::Add('CS CZ', 'Czech', 'Čeština', [
'Class:UserLDAP' => 'LDAP uživatel',
'Class:UserLDAP+' => 'Uživatel ověřen přes LDAP',
'UserLDAP:server' => 'Specifika LDAP',
));
//
// Class: UserLDAP
//
Dict::Add('CS CZ', 'Czech', 'Čeština', array(
'Class:UserLDAP/Attribute:ldap_server' => 'Ldap server~~',
'Class:UserLDAP/Attribute:ldap_server+' => '~~',
));
]);

View File

@@ -10,17 +10,8 @@
* @author Erik Bøg <erik@boegmoeller.dk>
*
*/
Dict::Add('DA DA', 'Danish', 'Dansk', array(
Dict::Add('DA DA', 'Danish', 'Dansk', [
'Class:UserLDAP' => 'LDAP-Bruger',
'Class:UserLDAP+' => 'Bruger der godkendes via LDAP',
'UserLDAP:server' => 'LDAP specifics~~',
));
//
// Class: UserLDAP
//
Dict::Add('DA DA', 'Danish', 'Dansk', array(
'Class:UserLDAP/Attribute:ldap_server' => 'Ldap server~~',
'Class:UserLDAP/Attribute:ldap_server+' => '~~',
));
]);

View File

@@ -10,17 +10,10 @@
* @author ITOMIG GmbH <martin.raenker@itomig.de>
*
*/
Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', [
'Class:UserLDAP' => 'LDAP-Benutzer',
'Class:UserLDAP+' => 'Benutzer, der via LDAP authentifiziert wird',
'UserLDAP:server' => 'LDAP-Einstellungen',
));
//
// Class: UserLDAP
//
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:UserLDAP/Attribute:ldap_server' => 'LDAP-Server',
'Class:UserLDAP/Attribute:ldap_server+' => 'Optional: LDAP-Server, der zur Authentifizierung verwendet werden soll, falls mehrere LDAP-Server konfiguriert sind.',
));
'UserLDAP:server' => 'LDAP-Einstellungen',
]);

Some files were not shown because too many files have changed in this diff Show More