mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01:00
N°8796 - Add PHP code style validation in iTop and extensions - format whole code base
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// 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
|
// 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
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -23,30 +24,29 @@
|
|||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
class UserRightsMatrixClassGrant extends DBObject
|
class UserRightsMatrixClassGrant extends DBObject
|
||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "addon/userrights",
|
"category" => "addon/userrights",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "",
|
"name_attcode" => "",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_ur_matrixclasses",
|
"db_table" => "priv_ur_matrixclasses",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", ["targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("login", ["allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login"]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("class", array("allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("class", ["allowed_values" => null, "sql" => "class", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
|
|
||||||
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", ["allowed_values" => null, "sql" => "action", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
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 AttributeEnum("permission", ["allowed_values" => new ValueSetEnum('yes,no'), "sql" => "permission", "default_value" => "yes", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,25 +54,25 @@ class UserRightsMatrixClassStimulusGrant extends DBObject
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "addon/userrights",
|
"category" => "addon/userrights",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "",
|
"name_attcode" => "",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_ur_matrixclassesstimulus",
|
"db_table" => "priv_ur_matrixclassesstimulus",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", ["targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("login", ["allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login"]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("class", array("allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("class", ["allowed_values" => null, "sql" => "class", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
|
|
||||||
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", ["allowed_values" => null, "sql" => "action", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
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 AttributeEnum("permission", ["allowed_values" => new ValueSetEnum('yes,no'), "sql" => "permission", "default_value" => "yes", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,42 +80,39 @@ class UserRightsMatrixAttributeGrant extends DBObject
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "addon/userrights",
|
"category" => "addon/userrights",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "",
|
"name_attcode" => "",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_ur_matrixattributes",
|
"db_table" => "priv_ur_matrixattributes",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", ["targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("login", ["allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login"]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("class", array("allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("class", ["allowed_values" => null, "sql" => "class", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("attcode", array("allowed_values"=>null, "sql"=>"attcode", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("attcode", ["allowed_values" => null, "sql" => "attcode", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
|
|
||||||
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", ["allowed_values" => null, "sql" => "action", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
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 AttributeEnum("permission", ["allowed_values" => new ValueSetEnum('yes,no'), "sql" => "permission", "default_value" => "yes", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class UserRightsMatrix extends UserRightsAddOnAPI
|
class UserRightsMatrix extends UserRightsAddOnAPI
|
||||||
{
|
{
|
||||||
static public $m_aActionCodes = array(
|
public static $m_aActionCodes = [
|
||||||
UR_ACTION_READ => 'read',
|
UR_ACTION_READ => 'read',
|
||||||
UR_ACTION_MODIFY => 'modify',
|
UR_ACTION_MODIFY => 'modify',
|
||||||
UR_ACTION_DELETE => 'delete',
|
UR_ACTION_DELETE => 'delete',
|
||||||
UR_ACTION_BULK_READ => 'bulk read',
|
UR_ACTION_BULK_READ => 'bulk read',
|
||||||
UR_ACTION_BULK_MODIFY => 'bulk modify',
|
UR_ACTION_BULK_MODIFY => 'bulk modify',
|
||||||
UR_ACTION_BULK_DELETE => 'bulk delete',
|
UR_ACTION_BULK_DELETE => 'bulk delete',
|
||||||
);
|
];
|
||||||
|
|
||||||
// Installation: create the very first user
|
// Installation: create the very first user
|
||||||
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
|
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
|
||||||
@@ -149,8 +146,7 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
// Users must be added manually
|
// Users must be added manually
|
||||||
// This procedure will then update the matrix when a new user is found or a new class/attribute appears
|
// This procedure will then update the matrix when a new user is found or a new class/attribute appears
|
||||||
$oUserSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT User"));
|
$oUserSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT User"));
|
||||||
while ($oUser = $oUserSet->Fetch())
|
while ($oUser = $oUserSet->Fetch()) {
|
||||||
{
|
|
||||||
$this->SetupUser($oUser->GetKey());
|
$this->SetupUser($oUser->GetKey());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -158,23 +154,16 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
|
|
||||||
protected function SetupUser($iUserId, $bNewUser = false)
|
protected function SetupUser($iUserId, $bNewUser = false)
|
||||||
{
|
{
|
||||||
foreach(array('bizmodel', 'application', 'gui', 'core/cmdb') as $sCategory)
|
foreach (['bizmodel', 'application', 'gui', 'core/cmdb'] as $sCategory) {
|
||||||
{
|
foreach (MetaModel::GetClasses($sCategory) as $sClass) {
|
||||||
foreach (MetaModel::GetClasses($sCategory) as $sClass)
|
foreach (self::$m_aActionCodes as $iActionCode => $sAction) {
|
||||||
{
|
if ($bNewUser) {
|
||||||
foreach (self::$m_aActionCodes as $iActionCode => $sAction)
|
|
||||||
{
|
|
||||||
if ($bNewUser)
|
|
||||||
{
|
|
||||||
$bAddCell = true;
|
$bAddCell = true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassGrant WHERE class = '$sClass' AND action = '$sAction' AND userid = $iUserId"));
|
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassGrant WHERE class = '$sClass' AND action = '$sAction' AND userid = $iUserId"));
|
||||||
$bAddCell = ($oSet->Count() < 1);
|
$bAddCell = ($oSet->Count() < 1);
|
||||||
}
|
}
|
||||||
if ($bAddCell)
|
if ($bAddCell) {
|
||||||
{
|
|
||||||
// Create a new entry
|
// Create a new entry
|
||||||
$oMyClassGrant = MetaModel::NewObject("UserRightsMatrixClassGrant");
|
$oMyClassGrant = MetaModel::NewObject("UserRightsMatrixClassGrant");
|
||||||
$oMyClassGrant->Set("userid", $iUserId);
|
$oMyClassGrant->Set("userid", $iUserId);
|
||||||
@@ -184,19 +173,14 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
$iId = $oMyClassGrant->DBInsertNoReload();
|
$iId = $oMyClassGrant->DBInsertNoReload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $oStimulus)
|
foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $oStimulus) {
|
||||||
{
|
if ($bNewUser) {
|
||||||
if ($bNewUser)
|
|
||||||
{
|
|
||||||
$bAddCell = true;
|
$bAddCell = true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassStimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND userid = $iUserId"));
|
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassStimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND userid = $iUserId"));
|
||||||
$bAddCell = ($oSet->Count() < 1);
|
$bAddCell = ($oSet->Count() < 1);
|
||||||
}
|
}
|
||||||
if ($bAddCell)
|
if ($bAddCell) {
|
||||||
{
|
|
||||||
// Create a new entry
|
// Create a new entry
|
||||||
$oMyClassGrant = MetaModel::NewObject("UserRightsMatrixClassStimulusGrant");
|
$oMyClassGrant = MetaModel::NewObject("UserRightsMatrixClassStimulusGrant");
|
||||||
$oMyClassGrant->Set("userid", $iUserId);
|
$oMyClassGrant->Set("userid", $iUserId);
|
||||||
@@ -206,21 +190,15 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
$iId = $oMyClassGrant->DBInsertNoReload();
|
$iId = $oMyClassGrant->DBInsertNoReload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (MetaModel::GetAttributesList($sClass) as $sAttCode)
|
foreach (MetaModel::GetAttributesList($sClass) as $sAttCode) {
|
||||||
{
|
if ($bNewUser) {
|
||||||
if ($bNewUser)
|
|
||||||
{
|
|
||||||
$bAddCell = true;
|
$bAddCell = true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixAttributeGrant WHERE class = '$sClass' AND attcode = '$sAttCode' AND userid = $iUserId"));
|
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixAttributeGrant WHERE class = '$sClass' AND attcode = '$sAttCode' AND userid = $iUserId"));
|
||||||
$bAddCell = ($oSet->Count() < 1);
|
$bAddCell = ($oSet->Count() < 1);
|
||||||
}
|
}
|
||||||
if ($bAddCell)
|
if ($bAddCell) {
|
||||||
{
|
foreach (['read', 'modify'] as $sAction) {
|
||||||
foreach (array('read', 'modify') as $sAction)
|
|
||||||
{
|
|
||||||
// Create a new entry
|
// Create a new entry
|
||||||
$oMyAttGrant = MetaModel::NewObject("UserRightsMatrixAttributeGrant");
|
$oMyAttGrant = MetaModel::NewObject("UserRightsMatrixAttributeGrant");
|
||||||
$oMyAttGrant->Set("userid", $iUserId);
|
$oMyAttGrant->Set("userid", $iUserId);
|
||||||
@@ -261,14 +239,13 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function Init()
|
public function Init()
|
||||||
{
|
{
|
||||||
// Could be loaded in a shared memory (?)
|
// Could be loaded in a shared memory (?)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetSelectFilter($oUser, $sClass, $aSettings = array())
|
public function GetSelectFilter($oUser, $sClass, $aSettings = [])
|
||||||
{
|
{
|
||||||
$oNullFilter = new DBObjectSearch($sClass);
|
$oNullFilter = new DBObjectSearch($sClass);
|
||||||
return $oNullFilter;
|
return $oNullFilter;
|
||||||
@@ -276,21 +253,18 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
|
|
||||||
public function IsActionAllowed($oUser, $sClass, $iActionCode, $oInstanceSet = null)
|
public function IsActionAllowed($oUser, $sClass, $iActionCode, $oInstanceSet = null)
|
||||||
{
|
{
|
||||||
if (!array_key_exists($iActionCode, self::$m_aActionCodes))
|
if (!array_key_exists($iActionCode, self::$m_aActionCodes)) {
|
||||||
{
|
|
||||||
return UR_ALLOWED_NO;
|
return UR_ALLOWED_NO;
|
||||||
}
|
}
|
||||||
$sAction = self::$m_aActionCodes[$iActionCode];
|
$sAction = self::$m_aActionCodes[$iActionCode];
|
||||||
|
|
||||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassGrant WHERE class = '$sClass' AND action = '$sAction' AND userid = '{$oUser->GetKey()}'"));
|
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassGrant WHERE class = '$sClass' AND action = '$sAction' AND userid = '{$oUser->GetKey()}'"));
|
||||||
if ($oSet->Count() < 1)
|
if ($oSet->Count() < 1) {
|
||||||
{
|
|
||||||
return UR_ALLOWED_NO;
|
return UR_ALLOWED_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
$oGrantRecord = $oSet->Fetch();
|
$oGrantRecord = $oSet->Fetch();
|
||||||
switch ($oGrantRecord->Get('permission'))
|
switch ($oGrantRecord->Get('permission')) {
|
||||||
{
|
|
||||||
case 'yes':
|
case 'yes':
|
||||||
$iRetCode = UR_ALLOWED_YES;
|
$iRetCode = UR_ALLOWED_YES;
|
||||||
break;
|
break;
|
||||||
@@ -304,21 +278,18 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
|
|
||||||
public function IsActionAllowedOnAttribute($oUser, $sClass, $sAttCode, $iActionCode, $oInstanceSet = null)
|
public function IsActionAllowedOnAttribute($oUser, $sClass, $sAttCode, $iActionCode, $oInstanceSet = null)
|
||||||
{
|
{
|
||||||
if (!array_key_exists($iActionCode, self::$m_aActionCodes))
|
if (!array_key_exists($iActionCode, self::$m_aActionCodes)) {
|
||||||
{
|
|
||||||
return UR_ALLOWED_NO;
|
return UR_ALLOWED_NO;
|
||||||
}
|
}
|
||||||
$sAction = self::$m_aActionCodes[$iActionCode];
|
$sAction = self::$m_aActionCodes[$iActionCode];
|
||||||
|
|
||||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixAttributeGrant WHERE class = '$sClass' AND attcode = '$sAttCode' AND action = '$sAction' AND userid = '{$oUser->GetKey()}'"));
|
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixAttributeGrant WHERE class = '$sClass' AND attcode = '$sAttCode' AND action = '$sAction' AND userid = '{$oUser->GetKey()}'"));
|
||||||
if ($oSet->Count() < 1)
|
if ($oSet->Count() < 1) {
|
||||||
{
|
|
||||||
return UR_ALLOWED_NO;
|
return UR_ALLOWED_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
$oGrantRecord = $oSet->Fetch();
|
$oGrantRecord = $oSet->Fetch();
|
||||||
switch ($oGrantRecord->Get('permission'))
|
switch ($oGrantRecord->Get('permission')) {
|
||||||
{
|
|
||||||
case 'yes':
|
case 'yes':
|
||||||
$iRetCode = UR_ALLOWED_YES;
|
$iRetCode = UR_ALLOWED_YES;
|
||||||
break;
|
break;
|
||||||
@@ -333,14 +304,12 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
public function IsStimulusAllowed($oUser, $sClass, $sStimulusCode, $oInstanceSet = null)
|
public function IsStimulusAllowed($oUser, $sClass, $sStimulusCode, $oInstanceSet = null)
|
||||||
{
|
{
|
||||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassStimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND userid = '{$oUser->GetKey()}'"));
|
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassStimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND userid = '{$oUser->GetKey()}'"));
|
||||||
if ($oSet->Count() < 1)
|
if ($oSet->Count() < 1) {
|
||||||
{
|
|
||||||
return UR_ALLOWED_NO;
|
return UR_ALLOWED_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
$oGrantRecord = $oSet->Fetch();
|
$oGrantRecord = $oSet->Fetch();
|
||||||
switch ($oGrantRecord->Get('permission'))
|
switch ($oGrantRecord->Get('permission')) {
|
||||||
{
|
|
||||||
case 'yes':
|
case 'yes':
|
||||||
$iRetCode = UR_ALLOWED_YES;
|
$iRetCode = UR_ALLOWED_YES;
|
||||||
break;
|
break;
|
||||||
@@ -358,5 +327,3 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
UserRights::SelectModule('UserRightsMatrix');
|
UserRights::SelectModule('UserRightsMatrix');
|
||||||
|
|
||||||
?>
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// 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
|
// 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
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -47,7 +48,7 @@ class UserRightsNull extends UserRightsAddOnAPI
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetSelectFilter($oUser, $sClass, $aSettings = array())
|
public function GetSelectFilter($oUser, $sClass, $aSettings = [])
|
||||||
{
|
{
|
||||||
$oNullFilter = new DBObjectSearch($sClass);
|
$oNullFilter = new DBObjectSearch($sClass);
|
||||||
return $oNullFilter;
|
return $oNullFilter;
|
||||||
@@ -74,5 +75,3 @@ class UserRightsNull extends UserRightsAddOnAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
UserRights::SelectModule('UserRightsNull');
|
UserRights::SelectModule('UserRightsNull');
|
||||||
|
|
||||||
?>
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -29,56 +30,52 @@ class UserRightsBaseClassGUI extends cmdbAbstractObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class URP_Profiles extends UserRightsBaseClassGUI
|
class URP_Profiles extends UserRightsBaseClassGUI
|
||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "addon/userrights,grant_by_profile,filter",
|
"category" => "addon/userrights,grant_by_profile,filter",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"complementary_name_attcode" => array('description'),
|
"complementary_name_attcode" => ['description'],
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_urp_profiles",
|
"db_table" => "priv_urp_profiles",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("name", ["allowed_values" => null, "sql" => "name", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("description", ["allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("user_list", array("linked_class"=>"URP_UserProfile", "ext_key_to_me"=>"profileid", "ext_key_to_remote"=>"userid", "allowed_values"=>null, "count_min"=>1, "count_max"=>0, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("user_list", ["linked_class" => "URP_UserProfile", "ext_key_to_me" => "profileid", "ext_key_to_remote" => "userid", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => []]));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'user_list')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['name', 'description', 'user_list']); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('description')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', ['description']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('name','description')); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', ['name','description']); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('default_search', array ('name','description'));
|
MetaModel::Init_SetZListItems('default_search', ['name','description']);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static $m_aCacheProfiles = null;
|
protected static $m_aCacheProfiles = null;
|
||||||
|
|
||||||
public static function DoCreateProfile($sName, $sDescription)
|
public static function DoCreateProfile($sName, $sDescription)
|
||||||
{
|
{
|
||||||
if (is_null(self::$m_aCacheProfiles))
|
if (is_null(self::$m_aCacheProfiles)) {
|
||||||
{
|
self::$m_aCacheProfiles = [];
|
||||||
self::$m_aCacheProfiles = array();
|
|
||||||
$oFilterAll = new DBObjectSearch('URP_Profiles');
|
$oFilterAll = new DBObjectSearch('URP_Profiles');
|
||||||
$oSet = new DBObjectSet($oFilterAll);
|
$oSet = new DBObjectSet($oFilterAll);
|
||||||
while ($oProfile = $oSet->Fetch())
|
while ($oProfile = $oSet->Fetch()) {
|
||||||
{
|
|
||||||
self::$m_aCacheProfiles[$oProfile->Get('name')] = $oProfile->GetKey();
|
self::$m_aCacheProfiles[$oProfile->Get('name')] = $oProfile->GetKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sCacheKey = $sName;
|
$sCacheKey = $sName;
|
||||||
if (isset(self::$m_aCacheProfiles[$sCacheKey]))
|
if (isset(self::$m_aCacheProfiles[$sCacheKey])) {
|
||||||
{
|
|
||||||
return self::$m_aCacheProfiles[$sCacheKey];
|
return self::$m_aCacheProfiles[$sCacheKey];
|
||||||
}
|
}
|
||||||
$oNewObj = MetaModel::NewObject("URP_Profiles");
|
$oNewObj = MetaModel::NewObject("URP_Profiles");
|
||||||
@@ -89,27 +86,21 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
return $iId;
|
return $iId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function GetGrantAsHtml($oUserRights, $sClass, $sAction)
|
public function GetGrantAsHtml($oUserRights, $sClass, $sAction)
|
||||||
{
|
{
|
||||||
$bGrant = $oUserRights->GetProfileActionGrant($this->GetKey(), $sClass, $sAction);
|
$bGrant = $oUserRights->GetProfileActionGrant($this->GetKey(), $sClass, $sAction);
|
||||||
if (is_null($bGrant))
|
if (is_null($bGrant)) {
|
||||||
{
|
|
||||||
return '<span class="ibo-user-rights ibo-is-failure">'.Dict::S('UI:UserManagement:ActionAllowed:No').'</span>';
|
return '<span class="ibo-user-rights ibo-is-failure">'.Dict::S('UI:UserManagement:ActionAllowed:No').'</span>';
|
||||||
}
|
} elseif ($bGrant) {
|
||||||
elseif ($bGrant)
|
|
||||||
{
|
|
||||||
return '<span class="ibo-user-rights ibo-is-success">'.Dict::S('UI:UserManagement:ActionAllowed:Yes').'</span>';
|
return '<span class="ibo-user-rights ibo-is-success">'.Dict::S('UI:UserManagement:ActionAllowed:Yes').'</span>';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return '<span class="ibo-user-rights ibo-is-failure">'.Dict::S('UI:UserManagement:ActionAllowed:No').'</span>';
|
return '<span class="ibo-user-rights ibo-is-failure">'.Dict::S('UI:UserManagement:ActionAllowed:No').'</span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function DoShowGrantSumary($oPage)
|
public function DoShowGrantSumary($oPage)
|
||||||
{
|
{
|
||||||
if ($this->GetRawName() == "Administrator")
|
if ($this->GetRawName() == "Administrator") {
|
||||||
{
|
|
||||||
// Looks dirty, but ok that's THE ONE
|
// Looks dirty, but ok that's THE ONE
|
||||||
$oPage->p(Dict::S('UI:UserManagement:AdminProfile+'));
|
$oPage->p(Dict::S('UI:UserManagement:AdminProfile+'));
|
||||||
return;
|
return;
|
||||||
@@ -118,21 +109,18 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
// Note: for sure, we assume that the instance is derived from UserRightsProfile
|
// Note: for sure, we assume that the instance is derived from UserRightsProfile
|
||||||
$oUserRights = UserRights::GetModuleInstance();
|
$oUserRights = UserRights::GetModuleInstance();
|
||||||
|
|
||||||
$aDisplayData = array();
|
$aDisplayData = [];
|
||||||
foreach (MetaModel::GetClasses('bizmodel,grant_by_profile') as $sClass)
|
foreach (MetaModel::GetClasses('bizmodel,grant_by_profile') as $sClass) {
|
||||||
{
|
$aStimuli = [];
|
||||||
$aStimuli = array();
|
foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $oStimulus) {
|
||||||
foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $oStimulus)
|
|
||||||
{
|
|
||||||
$bGrant = $oUserRights->GetClassStimulusGrant($this->GetKey(), $sClass, $sStimulusCode);
|
$bGrant = $oUserRights->GetClassStimulusGrant($this->GetKey(), $sClass, $sStimulusCode);
|
||||||
if ($bGrant === true)
|
if ($bGrant === true) {
|
||||||
{
|
|
||||||
$aStimuli[] = '<span title="'.$sStimulusCode.': '.utils::EscapeHtml($oStimulus->GetDescription()).'">'.utils::EscapeHtml($oStimulus->GetLabel()).'</span>';
|
$aStimuli[] = '<span title="'.$sStimulusCode.': '.utils::EscapeHtml($oStimulus->GetDescription()).'">'.utils::EscapeHtml($oStimulus->GetLabel()).'</span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$sStimuli = implode(', ', $aStimuli);
|
$sStimuli = implode(', ', $aStimuli);
|
||||||
|
|
||||||
$aDisplayData[] = array(
|
$aDisplayData[] = [
|
||||||
'class' => MetaModel::GetName($sClass),
|
'class' => MetaModel::GetName($sClass),
|
||||||
'read' => $this->GetGrantAsHtml($oUserRights, $sClass, 'r'),
|
'read' => $this->GetGrantAsHtml($oUserRights, $sClass, 'r'),
|
||||||
'bulkread' => $this->GetGrantAsHtml($oUserRights, $sClass, 'br'),
|
'bulkread' => $this->GetGrantAsHtml($oUserRights, $sClass, 'br'),
|
||||||
@@ -141,22 +129,22 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
'delete' => $this->GetGrantAsHtml($oUserRights, $sClass, 'd'),
|
'delete' => $this->GetGrantAsHtml($oUserRights, $sClass, 'd'),
|
||||||
'bulkdelete' => $this->GetGrantAsHtml($oUserRights, $sClass, 'bd'),
|
'bulkdelete' => $this->GetGrantAsHtml($oUserRights, $sClass, 'bd'),
|
||||||
'stimuli' => $sStimuli,
|
'stimuli' => $sStimuli,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$aDisplayConfig = array();
|
$aDisplayConfig = [];
|
||||||
$aDisplayConfig['class'] = array('label' => Dict::S('UI:UserManagement:Class'), 'description' => Dict::S('UI:UserManagement:Class+'));
|
$aDisplayConfig['class'] = ['label' => Dict::S('UI:UserManagement:Class'), 'description' => Dict::S('UI:UserManagement:Class+')];
|
||||||
$aDisplayConfig['read'] = array('label' => Dict::S('UI:UserManagement:Action:Read'), 'description' => Dict::S('UI:UserManagement:Action:Read+'));
|
$aDisplayConfig['read'] = ['label' => Dict::S('UI:UserManagement:Action:Read'), 'description' => Dict::S('UI:UserManagement:Action:Read+')];
|
||||||
$aDisplayConfig['bulkread'] = array('label' => Dict::S('UI:UserManagement:Action:BulkRead'), 'description' => Dict::S('UI:UserManagement:Action:BulkRead+'));
|
$aDisplayConfig['bulkread'] = ['label' => Dict::S('UI:UserManagement:Action:BulkRead'), 'description' => Dict::S('UI:UserManagement:Action:BulkRead+')];
|
||||||
$aDisplayConfig['write'] = array('label' => Dict::S('UI:UserManagement:Action:Modify'), 'description' => Dict::S('UI:UserManagement:Action:Modify+'));
|
$aDisplayConfig['write'] = ['label' => Dict::S('UI:UserManagement:Action:Modify'), 'description' => Dict::S('UI:UserManagement:Action:Modify+')];
|
||||||
$aDisplayConfig['bulkwrite'] = array('label' => Dict::S('UI:UserManagement:Action:BulkModify'), 'description' => Dict::S('UI:UserManagement:Action:BulkModify+'));
|
$aDisplayConfig['bulkwrite'] = ['label' => Dict::S('UI:UserManagement:Action:BulkModify'), 'description' => Dict::S('UI:UserManagement:Action:BulkModify+')];
|
||||||
$aDisplayConfig['delete'] = array('label' => Dict::S('UI:UserManagement:Action:Delete'), 'description' => Dict::S('UI:UserManagement:Action:Delete+'));
|
$aDisplayConfig['delete'] = ['label' => Dict::S('UI:UserManagement:Action:Delete'), 'description' => Dict::S('UI:UserManagement:Action:Delete+')];
|
||||||
$aDisplayConfig['bulkdelete'] = array('label' => Dict::S('UI:UserManagement:Action:BulkDelete'), 'description' => Dict::S('UI:UserManagement:Action:BulkDelete+'));
|
$aDisplayConfig['bulkdelete'] = ['label' => Dict::S('UI:UserManagement:Action:BulkDelete'), 'description' => Dict::S('UI:UserManagement:Action:BulkDelete+')];
|
||||||
$aDisplayConfig['stimuli'] = array('label' => Dict::S('UI:UserManagement:Action:Stimuli'), 'description' => Dict::S('UI:UserManagement:Action:Stimuli+'));
|
$aDisplayConfig['stimuli'] = ['label' => Dict::S('UI:UserManagement:Action:Stimuli'), 'description' => Dict::S('UI:UserManagement:Action:Stimuli+')];
|
||||||
$oPage->table($aDisplayConfig, $aDisplayData);
|
$oPage->table($aDisplayConfig, $aDisplayData);
|
||||||
}
|
}
|
||||||
|
|
||||||
function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
|
public function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
|
||||||
{
|
{
|
||||||
parent::DisplayBareRelations($oPage, $bEditMode);
|
parent::DisplayBareRelations($oPage, $bEditMode);
|
||||||
|
|
||||||
@@ -166,10 +154,9 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
|
|
||||||
public static function GetReadOnlyAttributes()
|
public static function GetReadOnlyAttributes()
|
||||||
{
|
{
|
||||||
return array('name', 'description');
|
return ['name', 'description'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// returns an array of id => array of column => php value(so-called "real value")
|
// returns an array of id => array of column => php value(so-called "real value")
|
||||||
public static function GetPredefinedObjects()
|
public static function GetPredefinedObjects()
|
||||||
{
|
{
|
||||||
@@ -181,15 +168,13 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
protected function OnDelete()
|
protected function OnDelete()
|
||||||
{
|
{
|
||||||
// Don't remove admin profile
|
// Don't remove admin profile
|
||||||
if ($this->Get('name') === ADMIN_PROFILE_NAME)
|
if ($this->Get('name') === ADMIN_PROFILE_NAME) {
|
||||||
{
|
|
||||||
throw new SecurityException(Dict::Format('UI:Login:Error:AccessAdmin'));
|
throw new SecurityException(Dict::Format('UI:Login:Error:AccessAdmin'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: this may break the rule that says: "a user must have at least ONE profile" !
|
// Note: this may break the rule that says: "a user must have at least ONE profile" !
|
||||||
$oLnkSet = $this->Get('user_list');
|
$oLnkSet = $this->Get('user_list');
|
||||||
while($oLnk = $oLnkSet->Fetch())
|
while ($oLnk = $oLnkSet->Fetch()) {
|
||||||
{
|
|
||||||
$oLnk->DBDelete();
|
$oLnk->DBDelete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,11 +187,10 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
* @param $sTargetState string The target state in which to evalutate the flags, if empty the current state will be used
|
* @param $sTargetState string The target state in which to evalutate the flags, if empty the current state will be used
|
||||||
* @return integer Flags: the binary combination of the flags applicable to this attribute
|
* @return integer Flags: the binary combination of the flags applicable to this attribute
|
||||||
*/
|
*/
|
||||||
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
public function GetAttributeFlags($sAttCode, &$aReasons = [], $sTargetState = '')
|
||||||
{
|
{
|
||||||
$iFlags = parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
$iFlags = parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||||
if (MetaModel::GetConfig()->Get('demo_mode'))
|
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
||||||
{
|
|
||||||
$aReasons[] = 'Sorry, profiles are read-only in the demonstration mode!';
|
$aReasons[] = 'Sorry, profiles are read-only in the demonstration mode!';
|
||||||
$iFlags |= OPT_ATT_READONLY;
|
$iFlags |= OPT_ATT_READONLY;
|
||||||
}
|
}
|
||||||
@@ -214,52 +198,52 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class URP_UserProfile extends UserRightsBaseClassGUI
|
class URP_UserProfile extends UserRightsBaseClassGUI
|
||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "addon/userrights,grant_by_profile,filter",
|
"category" => "addon/userrights,grant_by_profile,filter",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => array("userlogin", "profile"),
|
"name_attcode" => ["userlogin", "profile"],
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_urp_userprofile",
|
"db_table" => "priv_urp_userprofile",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"is_link" => true, /** @since 3.1.0 N°6482 */
|
"is_link" => true, /** @since 3.1.0 N°6482 */
|
||||||
'uniqueness_rules' => array(
|
'uniqueness_rules' => [
|
||||||
'no_duplicate' => array(
|
'no_duplicate' => [
|
||||||
'attributes' => array(
|
'attributes' => [
|
||||||
0 => 'userid',
|
0 => 'userid',
|
||||||
1 => 'profileid',
|
1 => 'profileid',
|
||||||
),
|
],
|
||||||
'filter' => '',
|
'filter' => '',
|
||||||
'disabled' => false,
|
'disabled' => false,
|
||||||
'is_blocking' => true,
|
'is_blocking' => true,
|
||||||
),
|
],
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", ["targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", array("allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", ["allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login"]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid",
|
MetaModel::Init_AddAttribute(new AttributeExternalKey(
|
||||||
array("targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array(), "allow_target_creation" => false)));
|
"profileid",
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name")));
|
["targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => [], "allow_target_creation" => false]
|
||||||
|
));
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", ["allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name"]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("reason", array("allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeString("reason", ["allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('userid', 'profileid', 'reason')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['userid', 'profileid', 'reason']); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('userid', 'profileid', 'reason')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', ['userid', 'profileid', 'reason']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('userid', 'profileid')); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', ['userid', 'profileid']); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('advanced_search', array('userid', 'profileid')); // Criteria of the advanced search form
|
MetaModel::Init_SetZListItems('advanced_search', ['userid', 'profileid']); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
|
|
||||||
public function CheckToDelete(&$oDeletionPlan)
|
public function CheckToDelete(&$oDeletionPlan)
|
||||||
@@ -267,15 +251,14 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
|||||||
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
||||||
// Users deletion is NOT allowed in demo mode
|
// Users deletion is NOT allowed in demo mode
|
||||||
$oDeletionPlan->AddToDelete($this, null);
|
$oDeletionPlan->AddToDelete($this, null);
|
||||||
$oDeletionPlan->SetDeletionIssues($this, array('deletion not allowed in demo mode.'), true);
|
$oDeletionPlan->SetDeletionIssues($this, ['deletion not allowed in demo mode.'], true);
|
||||||
$oDeletionPlan->ComputeResults();
|
$oDeletionPlan->ComputeResults();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$this->CheckIfProfileIsAllowed(UR_ACTION_DELETE);
|
$this->CheckIfProfileIsAllowed(UR_ACTION_DELETE);
|
||||||
}
|
} catch (SecurityException $e) {
|
||||||
catch (SecurityException $e) {
|
|
||||||
// Users deletion is NOT allowed
|
// Users deletion is NOT allowed
|
||||||
$oDeletionPlan->AddToDelete($this, null);
|
$oDeletionPlan->AddToDelete($this, null);
|
||||||
$oDeletionPlan->SetDeletionIssues($this, [$e->getMessage()], true);
|
$oDeletionPlan->SetDeletionIssues($this, [$e->getMessage()], true);
|
||||||
@@ -292,15 +275,14 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
|||||||
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
||||||
// Users deletion is NOT allowed in demo mode
|
// Users deletion is NOT allowed in demo mode
|
||||||
$oDeletionPlan->AddToDelete($this, null);
|
$oDeletionPlan->AddToDelete($this, null);
|
||||||
$oDeletionPlan->SetDeletionIssues($this, array('deletion not allowed in demo mode.'), true);
|
$oDeletionPlan->SetDeletionIssues($this, ['deletion not allowed in demo mode.'], true);
|
||||||
$oDeletionPlan->ComputeResults();
|
$oDeletionPlan->ComputeResults();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$this->CheckIfProfileIsAllowed(UR_ACTION_DELETE);
|
$this->CheckIfProfileIsAllowed(UR_ACTION_DELETE);
|
||||||
}
|
} catch (SecurityException $e) {
|
||||||
catch (SecurityException $e) {
|
|
||||||
// Users deletion is NOT allowed
|
// Users deletion is NOT allowed
|
||||||
$oDeletionPlan->AddToDelete($this, null);
|
$oDeletionPlan->AddToDelete($this, null);
|
||||||
$oDeletionPlan->SetDeletionIssues($this, [$e->getMessage()], true);
|
$oDeletionPlan->SetDeletionIssues($this, [$e->getMessage()], true);
|
||||||
@@ -336,29 +318,26 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
|||||||
protected function CheckIfProfileIsAllowed($iActionCode)
|
protected function CheckIfProfileIsAllowed($iActionCode)
|
||||||
{
|
{
|
||||||
// When initializing or admin, we need to let everything pass trough
|
// When initializing or admin, we need to let everything pass trough
|
||||||
if (!UserRights::IsLoggedIn() || UserRights::IsAdministrator()) { return; }
|
if (!UserRights::IsLoggedIn() || UserRights::IsAdministrator()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Only administrators can manage administrators
|
// Only administrators can manage administrators
|
||||||
$iOrigUserId = $this->GetOriginal('userid');
|
$iOrigUserId = $this->GetOriginal('userid');
|
||||||
if (!empty($iOrigUserId))
|
if (!empty($iOrigUserId)) {
|
||||||
{
|
|
||||||
$oUser = MetaModel::GetObject('User', $iOrigUserId, true, true);
|
$oUser = MetaModel::GetObject('User', $iOrigUserId, true, true);
|
||||||
if (UserRights::IsAdministrator($oUser) && !UserRights::IsAdministrator())
|
if (UserRights::IsAdministrator($oUser) && !UserRights::IsAdministrator()) {
|
||||||
{
|
|
||||||
throw new SecurityException(Dict::Format('UI:Login:Error:AccessRestricted'));
|
throw new SecurityException(Dict::Format('UI:Login:Error:AccessRestricted'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$oUser = MetaModel::GetObject('User', $this->Get('userid'), true, true);
|
$oUser = MetaModel::GetObject('User', $this->Get('userid'), true, true);
|
||||||
if (UserRights::IsAdministrator($oUser) && !UserRights::IsAdministrator())
|
if (UserRights::IsAdministrator($oUser) && !UserRights::IsAdministrator()) {
|
||||||
{
|
|
||||||
throw new SecurityException(Dict::Format('UI:Login:Error:AccessRestricted'));
|
throw new SecurityException(Dict::Format('UI:Login:Error:AccessRestricted'));
|
||||||
}
|
}
|
||||||
if (!UserRights::IsActionAllowed(get_class($this), $iActionCode, DBObjectSet::FromObject($this)))
|
if (!UserRights::IsActionAllowed(get_class($this), $iActionCode, DBObjectSet::FromObject($this))) {
|
||||||
{
|
|
||||||
throw new SecurityException(Dict::Format('UI:Error:ObjectCannotBeUpdated'));
|
throw new SecurityException(Dict::Format('UI:Error:ObjectCannotBeUpdated'));
|
||||||
}
|
}
|
||||||
if (!UserRights::IsAdministrator() && ($this->Get('profile') === ADMIN_PROFILE_NAME))
|
if (!UserRights::IsAdministrator() && ($this->Get('profile') === ADMIN_PROFILE_NAME)) {
|
||||||
{
|
|
||||||
throw new SecurityException(Dict::Format('UI:Login:Error:AccessAdmin'));
|
throw new SecurityException(Dict::Format('UI:Login:Error:AccessAdmin'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -369,33 +348,33 @@ class URP_UserOrg extends UserRightsBaseClassGUI
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "addon/userrights,grant_by_profile",
|
"category" => "addon/userrights,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => array("userlogin", "allowed_org_name"),
|
"name_attcode" => ["userlogin", "allowed_org_name"],
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_urp_userorg",
|
"db_table" => "priv_urp_userorg",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", ["targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", ["allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login"]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("allowed_org_id", array("targetclass"=>"Organization", "jointype"=> "", "allowed_values"=>null, "sql"=>"allowed_org_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("allowed_org_id", ["targetclass" => "Organization", "jointype" => "", "allowed_values" => null, "sql" => "allowed_org_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("allowed_org_name", array("allowed_values"=>null, "extkey_attcode"=> 'allowed_org_id', "target_attcode"=>"name")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("allowed_org_name", ["allowed_values" => null, "extkey_attcode" => 'allowed_org_id', "target_attcode" => "name"]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("reason", array("allowed_values"=>null, "sql"=>"reason", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("reason", ["allowed_values" => null, "sql" => "reason", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('userid', 'allowed_org_id', 'reason')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['userid', 'allowed_org_id', 'reason']); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('allowed_org_id', 'reason')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', ['allowed_org_id', 'reason']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('userid', 'allowed_org_id')); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', ['userid', 'allowed_org_id']); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('advanced_search', array('userid', 'allowed_org_id')); // Criteria of the advanced search form
|
MetaModel::Init_SetZListItems('advanced_search', ['userid', 'allowed_org_id']); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function OnInsert()
|
protected function OnInsert()
|
||||||
@@ -418,40 +397,37 @@ class URP_UserOrg extends UserRightsBaseClassGUI
|
|||||||
*/
|
*/
|
||||||
protected function CheckIfOrgIsAllowed()
|
protected function CheckIfOrgIsAllowed()
|
||||||
{
|
{
|
||||||
if (!UserRights::IsLoggedIn() || UserRights::IsAdministrator()) { return; }
|
if (!UserRights::IsLoggedIn() || UserRights::IsAdministrator()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$oUser = UserRights::GetUserObject();
|
$oUser = UserRights::GetUserObject();
|
||||||
$oAddon = UserRights::GetModuleInstance();
|
$oAddon = UserRights::GetModuleInstance();
|
||||||
$aOrgs = $oAddon->GetUserOrgs($oUser, '');
|
$aOrgs = $oAddon->GetUserOrgs($oUser, '');
|
||||||
if (count($aOrgs) > 0)
|
if (count($aOrgs) > 0) {
|
||||||
{
|
|
||||||
$iOrigOrgId = $this->GetOriginal('allowed_org_id');
|
$iOrigOrgId = $this->GetOriginal('allowed_org_id');
|
||||||
if ((!empty($iOrigOrgId) && !in_array($iOrigOrgId, $aOrgs)) || !in_array($this->Get('allowed_org_id'), $aOrgs))
|
if ((!empty($iOrigOrgId) && !in_array($iOrigOrgId, $aOrgs)) || !in_array($this->Get('allowed_org_id'), $aOrgs)) {
|
||||||
{
|
|
||||||
throw new SecurityException(Dict::Format('Class:User/Error:OrganizationNotAllowed'));
|
throw new SecurityException(Dict::Format('Class:User/Error:OrganizationNotAllowed'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class UserRightsProfile extends UserRightsAddOnAPI
|
class UserRightsProfile extends UserRightsAddOnAPI
|
||||||
{
|
{
|
||||||
static public $m_aActionCodes = array(
|
public static $m_aActionCodes = [
|
||||||
UR_ACTION_READ => 'r',
|
UR_ACTION_READ => 'r',
|
||||||
UR_ACTION_MODIFY => 'w',
|
UR_ACTION_MODIFY => 'w',
|
||||||
UR_ACTION_DELETE => 'd',
|
UR_ACTION_DELETE => 'd',
|
||||||
UR_ACTION_BULK_READ => 'br',
|
UR_ACTION_BULK_READ => 'br',
|
||||||
UR_ACTION_BULK_MODIFY => 'bw',
|
UR_ACTION_BULK_MODIFY => 'bw',
|
||||||
UR_ACTION_BULK_DELETE => 'bd',
|
UR_ACTION_BULK_DELETE => 'bd',
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array $aUsersProfilesList Cache of users' profiles. Hash array of user ID => [profile ID => profile friendlyname, profile ID => profile friendlyname, ...]
|
* @var array $aUsersProfilesList Cache of users' profiles. Hash array of user ID => [profile ID => profile friendlyname, profile ID => profile friendlyname, ...]
|
||||||
* @since 2.7.10 3.0.4 3.1.1 3.2.0 N°6887
|
* @since 2.7.10 3.0.4 3.1.1 3.2.0 N°6887
|
||||||
*/
|
*/
|
||||||
private $aUsersProfilesList = [];
|
private $aUsersProfilesList = [];
|
||||||
|
|
||||||
// Installation: create the very first user
|
// Installation: create the very first user
|
||||||
@@ -472,8 +448,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
$oContact = MetaModel::NewObject('Person');
|
$oContact = MetaModel::NewObject('Person');
|
||||||
$oContact->Set('name', 'My last name');
|
$oContact->Set('name', 'My last name');
|
||||||
$oContact->Set('first_name', 'My first name');
|
$oContact->Set('first_name', 'My first name');
|
||||||
if (MetaModel::IsValidAttCode('Person', 'org_id'))
|
if (MetaModel::IsValidAttCode('Person', 'org_id')) {
|
||||||
{
|
|
||||||
$oContact->Set('org_id', $iOrgId);
|
$oContact->Set('org_id', $iOrgId);
|
||||||
}
|
}
|
||||||
$oContact->Set('email', 'my.email@foo.org');
|
$oContact->Set('email', 'my.email@foo.org');
|
||||||
@@ -481,20 +456,17 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$oUser = new UserLocal();
|
$oUser = new UserLocal();
|
||||||
$oUser->Set('login', $sAdminUser);
|
$oUser->Set('login', $sAdminUser);
|
||||||
$oUser->Set('password', $sAdminPwd);
|
$oUser->Set('password', $sAdminPwd);
|
||||||
if (MetaModel::IsValidAttCode('UserLocal', 'contactid') && ($iContactId != 0))
|
if (MetaModel::IsValidAttCode('UserLocal', 'contactid') && ($iContactId != 0)) {
|
||||||
{
|
|
||||||
$oUser->Set('contactid', $iContactId);
|
$oUser->Set('contactid', $iContactId);
|
||||||
}
|
}
|
||||||
$oUser->Set('language', $sLanguage); // Language was chosen during the installation
|
$oUser->Set('language', $sLanguage); // Language was chosen during the installation
|
||||||
|
|
||||||
// Add this user to the very specific 'admin' profile
|
// Add this user to the very specific 'admin' profile
|
||||||
$oAdminProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => ADMIN_PROFILE_NAME), true /*all data*/);
|
$oAdminProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", ['name' => ADMIN_PROFILE_NAME], true /*all data*/);
|
||||||
if (is_object($oAdminProfile))
|
if (is_object($oAdminProfile)) {
|
||||||
{
|
|
||||||
$oUserProfile = new URP_UserProfile();
|
$oUserProfile = new URP_UserProfile();
|
||||||
$oUserProfile->Set('profileid', $oAdminProfile->GetKey());
|
$oUserProfile->Set('profileid', $oAdminProfile->GetKey());
|
||||||
$oUserProfile->Set('reason', 'By definition, the administrator must have the administrator profile');
|
$oUserProfile->Set('reason', 'By definition, the administrator must have the administrator profile');
|
||||||
@@ -509,11 +481,11 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $m_aUserOrgs = array(); // userid -> array of orgid
|
protected $m_aUserOrgs = []; // userid -> array of orgid
|
||||||
protected $m_aAdministrators = null; // [user id]
|
protected $m_aAdministrators = null; // [user id]
|
||||||
|
|
||||||
// Built on demand, could be optimized if necessary (doing a query for each attribute that needs to be read)
|
// Built on demand, could be optimized if necessary (doing a query for each attribute that needs to be read)
|
||||||
protected $m_aObjectActionGrants = array();
|
protected $m_aObjectActionGrants = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read and cache organizations allowed to the given user
|
* Read and cache organizations allowed to the given user
|
||||||
@@ -528,31 +500,25 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
public function GetUserOrgs($oUser, $sClass)
|
public function GetUserOrgs($oUser, $sClass)
|
||||||
{
|
{
|
||||||
$iUser = $oUser->GetKey();
|
$iUser = $oUser->GetKey();
|
||||||
if (!array_key_exists($iUser, $this->m_aUserOrgs))
|
if (!array_key_exists($iUser, $this->m_aUserOrgs)) {
|
||||||
{
|
$this->m_aUserOrgs[$iUser] = [];
|
||||||
$this->m_aUserOrgs[$iUser] = array();
|
|
||||||
|
|
||||||
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass('Organization');
|
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass('Organization');
|
||||||
if ($sHierarchicalKeyCode !== false)
|
if ($sHierarchicalKeyCode !== false) {
|
||||||
{
|
|
||||||
$sUserOrgQuery = 'SELECT UserOrg, Org FROM Organization AS Org JOIN Organization AS Root ON Org.'.$sHierarchicalKeyCode.' BELOW Root.id JOIN URP_UserOrg AS UserOrg ON UserOrg.allowed_org_id = Root.id WHERE UserOrg.userid = :userid';
|
$sUserOrgQuery = 'SELECT UserOrg, Org FROM Organization AS Org JOIN Organization AS Root ON Org.'.$sHierarchicalKeyCode.' BELOW Root.id JOIN URP_UserOrg AS UserOrg ON UserOrg.allowed_org_id = Root.id WHERE UserOrg.userid = :userid';
|
||||||
$oUserOrgSet = new DBObjectSet(DBObjectSearch::FromOQL_AllData($sUserOrgQuery), array(), array('userid' => $iUser));
|
$oUserOrgSet = new DBObjectSet(DBObjectSearch::FromOQL_AllData($sUserOrgQuery), [], ['userid' => $iUser]);
|
||||||
while ($aRow = $oUserOrgSet->FetchAssoc())
|
while ($aRow = $oUserOrgSet->FetchAssoc()) {
|
||||||
{
|
|
||||||
$oOrg = $aRow['Org'];
|
$oOrg = $aRow['Org'];
|
||||||
$this->m_aUserOrgs[$iUser][] = $oOrg->GetKey();
|
$this->m_aUserOrgs[$iUser][] = $oOrg->GetKey();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oSearch = new DBObjectSearch('URP_UserOrg');
|
$oSearch = new DBObjectSearch('URP_UserOrg');
|
||||||
$oSearch->AllowAllData();
|
$oSearch->AllowAllData();
|
||||||
$oCondition = new BinaryExpression(new FieldExpression('userid'), '=', new VariableExpression('userid'));
|
$oCondition = new BinaryExpression(new FieldExpression('userid'), '=', new VariableExpression('userid'));
|
||||||
$oSearch->AddConditionExpression($oCondition);
|
$oSearch->AddConditionExpression($oCondition);
|
||||||
|
|
||||||
$oUserOrgSet = new DBObjectSet($oSearch, array(), array('userid' => $iUser));
|
$oUserOrgSet = new DBObjectSet($oSearch, [], ['userid' => $iUser]);
|
||||||
while ($oUserOrg = $oUserOrgSet->Fetch())
|
while ($oUserOrg = $oUserOrgSet->Fetch()) {
|
||||||
{
|
|
||||||
$this->m_aUserOrgs[$iUser][] = $oUserOrg->Get('allowed_org_id');
|
$this->m_aUserOrgs[$iUser][] = $oUserOrg->Get('allowed_org_id');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -563,21 +529,19 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
public function ResetCache()
|
public function ResetCache()
|
||||||
{
|
{
|
||||||
// Loaded by Load cache
|
// Loaded by Load cache
|
||||||
$this->m_aUserOrgs = array();
|
$this->m_aUserOrgs = [];
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
$this->m_aObjectActionGrants = array();
|
$this->m_aObjectActionGrants = [];
|
||||||
$this->m_aAdministrators = null;
|
$this->m_aAdministrators = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function LoadCache()
|
public function LoadCache()
|
||||||
{
|
{
|
||||||
static $bSharedObjectInitialized = false;
|
static $bSharedObjectInitialized = false;
|
||||||
if (!$bSharedObjectInitialized)
|
if (!$bSharedObjectInitialized) {
|
||||||
{
|
|
||||||
$bSharedObjectInitialized = true;
|
$bSharedObjectInitialized = true;
|
||||||
if (self::HasSharing())
|
if (self::HasSharing()) {
|
||||||
{
|
|
||||||
SharedObject::InitSharedClassProperties();
|
SharedObject::InitSharedClassProperties();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -615,45 +579,40 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
*/
|
*/
|
||||||
public function ListProfiles($oUser)
|
public function ListProfiles($oUser)
|
||||||
{
|
{
|
||||||
$aRet = array();
|
$aRet = [];
|
||||||
$oSearch = new DBObjectSearch('URP_UserProfile');
|
$oSearch = new DBObjectSearch('URP_UserProfile');
|
||||||
$oSearch->AllowAllData();
|
$oSearch->AllowAllData();
|
||||||
$oSearch->NoContextParameters();
|
$oSearch->NoContextParameters();
|
||||||
$oSearch->Addcondition('userid', $oUser->GetKey(), '=');
|
$oSearch->Addcondition('userid', $oUser->GetKey(), '=');
|
||||||
$oProfiles = new DBObjectSet($oSearch);
|
$oProfiles = new DBObjectSet($oSearch);
|
||||||
while ($oUserProfile = $oProfiles->Fetch())
|
while ($oUserProfile = $oProfiles->Fetch()) {
|
||||||
{
|
|
||||||
$aRet[$oUserProfile->Get('profileid')] = $oUserProfile->Get('profileid_friendlyname');
|
$aRet[$oUserProfile->Get('profileid')] = $oUserProfile->Get('profileid_friendlyname');
|
||||||
}
|
}
|
||||||
return $aRet;
|
return $aRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetSelectFilter($oUser, $sClass, $aSettings = array())
|
public function GetSelectFilter($oUser, $sClass, $aSettings = [])
|
||||||
{
|
{
|
||||||
$this->LoadCache();
|
$this->LoadCache();
|
||||||
|
|
||||||
// Let us pass an administrator for bypassing the grant matrix check in order to test this method without the need to set up a complex profile
|
// Let us pass an administrator for bypassing the grant matrix check in order to test this method without the need to set up a complex profile
|
||||||
// In the nominal case Administrators never end up here (since they completely bypass GetSelectFilter)
|
// In the nominal case Administrators never end up here (since they completely bypass GetSelectFilter)
|
||||||
if (!static::IsAdministrator($oUser) && (MetaModel::HasCategory($sClass, 'silo') || MetaModel::HasCategory($sClass, 'bizmodel')))
|
if (!static::IsAdministrator($oUser) && (MetaModel::HasCategory($sClass, 'silo') || MetaModel::HasCategory($sClass, 'bizmodel'))) {
|
||||||
{
|
|
||||||
// N°4354 - Categories 'silo' and 'bizmodel' do check the grant matrix. Whereas 'filter' always allows to read (but the result can be filtered)
|
// N°4354 - Categories 'silo' and 'bizmodel' do check the grant matrix. Whereas 'filter' always allows to read (but the result can be filtered)
|
||||||
$aObjectPermissions = $this->GetUserActionGrant($oUser, $sClass, UR_ACTION_READ);
|
$aObjectPermissions = $this->GetUserActionGrant($oUser, $sClass, UR_ACTION_READ);
|
||||||
if ($aObjectPermissions['permission'] == UR_ALLOWED_NO)
|
if ($aObjectPermissions['permission'] == UR_ALLOWED_NO) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$oFilter = true;
|
$oFilter = true;
|
||||||
$aConditions = array();
|
$aConditions = [];
|
||||||
|
|
||||||
// Determine if this class is part of a silo and build the filter for it
|
// Determine if this class is part of a silo and build the filter for it
|
||||||
$sAttCode = self::GetOwnerOrganizationAttCode($sClass);
|
$sAttCode = self::GetOwnerOrganizationAttCode($sClass);
|
||||||
if (!is_null($sAttCode))
|
if (!is_null($sAttCode)) {
|
||||||
{
|
|
||||||
$aUserOrgs = $this->GetUserOrgs($oUser, $sClass);
|
$aUserOrgs = $this->GetUserOrgs($oUser, $sClass);
|
||||||
if (count($aUserOrgs) > 0)
|
if (count($aUserOrgs) > 0) {
|
||||||
{
|
|
||||||
$oFilter = $this->MakeSelectFilter($sClass, $aUserOrgs, $aSettings, $sAttCode);
|
$oFilter = $this->MakeSelectFilter($sClass, $aUserOrgs, $aSettings, $sAttCode);
|
||||||
}
|
}
|
||||||
// else: No org means 'any org'
|
// else: No org means 'any org'
|
||||||
@@ -662,20 +621,15 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
|
|
||||||
// Specific conditions to hide, for non-administrators, the Administrator Users, the Administrator Profile and related links
|
// Specific conditions to hide, for non-administrators, the Administrator Users, the Administrator Profile and related links
|
||||||
// Note: when logged as an administrator, GetSelectFilter is completely bypassed.
|
// Note: when logged as an administrator, GetSelectFilter is completely bypassed.
|
||||||
if ($this->AdministratorsAreHidden())
|
if ($this->AdministratorsAreHidden()) {
|
||||||
{
|
if ($sClass == 'URP_Profiles') {
|
||||||
if ($sClass == 'URP_Profiles')
|
|
||||||
{
|
|
||||||
$oExpression = new FieldExpression('id', $sClass);
|
$oExpression = new FieldExpression('id', $sClass);
|
||||||
$oScalarExpr = new ScalarExpression(1);
|
$oScalarExpr = new ScalarExpression(1);
|
||||||
|
|
||||||
$aConditions[] = new BinaryExpression($oExpression, '!=', $oScalarExpr);
|
$aConditions[] = new BinaryExpression($oExpression, '!=', $oScalarExpr);
|
||||||
}
|
} elseif (($sClass == 'URP_UserProfile') || ($sClass == 'User') || (is_subclass_of($sClass, 'User'))) {
|
||||||
else if (($sClass == 'URP_UserProfile') || ($sClass == 'User') || (is_subclass_of($sClass, 'User')))
|
|
||||||
{
|
|
||||||
$aAdministrators = $this->GetAdministrators();
|
$aAdministrators = $this->GetAdministrators();
|
||||||
if (count($aAdministrators) > 0)
|
if (count($aAdministrators) > 0) {
|
||||||
{
|
|
||||||
$sAttCode = ($sClass == 'URP_UserProfile') ? 'userid' : 'id';
|
$sAttCode = ($sClass == 'URP_UserProfile') ? 'userid' : 'id';
|
||||||
$oExpression = new FieldExpression($sAttCode, $sClass);
|
$oExpression = new FieldExpression($sAttCode, $sClass);
|
||||||
$oListExpr = ListExpression::FromScalars($aAdministrators);
|
$oListExpr = ListExpression::FromScalars($aAdministrators);
|
||||||
@@ -685,17 +639,14 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handling of the added conditions
|
// Handling of the added conditions
|
||||||
if (count($aConditions) > 0)
|
if (count($aConditions) > 0) {
|
||||||
{
|
if ($oFilter === true) {
|
||||||
if($oFilter === true)
|
|
||||||
{
|
|
||||||
// No 'silo' filter, let's build a clean one
|
// No 'silo' filter, let's build a clean one
|
||||||
$oFilter = new DBObjectSearch($sClass);
|
$oFilter = new DBObjectSearch($sClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the conditions to the filter
|
// Add the conditions to the filter
|
||||||
foreach($aConditions as $oCondition)
|
foreach ($aConditions as $oCondition) {
|
||||||
{
|
|
||||||
$oFilter->AddConditionExpression($oCondition);
|
$oFilter->AddConditionExpression($oCondition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -710,10 +661,9 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
*/
|
*/
|
||||||
private function GetAdministrators()
|
private function GetAdministrators()
|
||||||
{
|
{
|
||||||
if ($this->m_aAdministrators === null)
|
if ($this->m_aAdministrators === null) {
|
||||||
{
|
|
||||||
// Find all administrators
|
// Find all administrators
|
||||||
$this->m_aAdministrators = array();
|
$this->m_aAdministrators = [];
|
||||||
$oAdministratorsFilter = new DBObjectSearch('User');
|
$oAdministratorsFilter = new DBObjectSearch('User');
|
||||||
$oLnkFilter = new DBObjectSearch('URP_UserProfile');
|
$oLnkFilter = new DBObjectSearch('URP_UserProfile');
|
||||||
$oExpression = new FieldExpression('profileid', 'URP_UserProfile');
|
$oExpression = new FieldExpression('profileid', 'URP_UserProfile');
|
||||||
@@ -723,9 +673,8 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
$oAdministratorsFilter->AddCondition_ReferencedBy($oLnkFilter, 'userid');
|
$oAdministratorsFilter->AddCondition_ReferencedBy($oLnkFilter, 'userid');
|
||||||
$oAdministratorsFilter->AllowAllData(true); // Mandatory to prevent infinite recursion !!
|
$oAdministratorsFilter->AllowAllData(true); // Mandatory to prevent infinite recursion !!
|
||||||
$oSet = new DBObjectSet($oAdministratorsFilter);
|
$oSet = new DBObjectSet($oAdministratorsFilter);
|
||||||
$oSet->OptimizeColumnLoad(array('User' => array('login')));
|
$oSet->OptimizeColumnLoad(['User' => ['login']]);
|
||||||
while($oUser = $oSet->Fetch())
|
while ($oUser = $oSet->Fetch()) {
|
||||||
{
|
|
||||||
$this->m_aAdministrators[] = $oUser->GetKey();
|
$this->m_aAdministrators[] = $oUser->GetKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -741,7 +690,6 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
return ((bool)MetaModel::GetConfig()->Get('security.hide_administrators'));
|
return ((bool)MetaModel::GetConfig()->Get('security.hide_administrators'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This verb has been made public to allow the development of an accurate feedback for the current configuration
|
// This verb has been made public to allow the development of an accurate feedback for the current configuration
|
||||||
public function GetProfileActionGrant($iProfile, $sClass, $sAction)
|
public function GetProfileActionGrant($iProfile, $sClass, $sAction)
|
||||||
{
|
{
|
||||||
@@ -758,33 +706,29 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
// load and cache permissions for the current user on the given class
|
// load and cache permissions for the current user on the given class
|
||||||
//
|
//
|
||||||
$iUser = $oUser->GetKey();
|
$iUser = $oUser->GetKey();
|
||||||
if (isset($this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode])){
|
if (isset($this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode])) {
|
||||||
$aTest = $this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode];
|
$aTest = $this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode];
|
||||||
if (is_array($aTest)) return $aTest;
|
if (is_array($aTest)) {
|
||||||
|
return $aTest;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sAction = self::$m_aActionCodes[$iActionCode];
|
$sAction = self::$m_aActionCodes[$iActionCode];
|
||||||
|
|
||||||
$bStatus = null;
|
$bStatus = null;
|
||||||
// Cache user's profiles
|
// Cache user's profiles
|
||||||
if(false === array_key_exists($iUser, $this->aUsersProfilesList)){
|
if (false === array_key_exists($iUser, $this->aUsersProfilesList)) {
|
||||||
$this->aUsersProfilesList[$iUser] = UserRights::ListProfiles($oUser);
|
$this->aUsersProfilesList[$iUser] = UserRights::ListProfiles($oUser);
|
||||||
}
|
}
|
||||||
// Call the API of UserRights because it caches the list for us
|
// Call the API of UserRights because it caches the list for us
|
||||||
foreach($this->aUsersProfilesList[$iUser] as $iProfile => $oProfile)
|
foreach ($this->aUsersProfilesList[$iUser] as $iProfile => $oProfile) {
|
||||||
{
|
|
||||||
$bGrant = $this->GetProfileActionGrant($iProfile, $sClass, $sAction);
|
$bGrant = $this->GetProfileActionGrant($iProfile, $sClass, $sAction);
|
||||||
if (!is_null($bGrant))
|
if (!is_null($bGrant)) {
|
||||||
{
|
if ($bGrant) {
|
||||||
if ($bGrant)
|
if (is_null($bStatus)) {
|
||||||
{
|
|
||||||
if (is_null($bStatus))
|
|
||||||
{
|
|
||||||
$bStatus = true;
|
$bStatus = true;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$bStatus = false;
|
$bStatus = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -792,9 +736,9 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
|
|
||||||
$iPermission = $bStatus ? UR_ALLOWED_YES : UR_ALLOWED_NO;
|
$iPermission = $bStatus ? UR_ALLOWED_YES : UR_ALLOWED_NO;
|
||||||
|
|
||||||
$aRes = array(
|
$aRes = [
|
||||||
'permission' => $iPermission,
|
'permission' => $iPermission,
|
||||||
);
|
];
|
||||||
$this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode] = $aRes;
|
$this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode] = $aRes;
|
||||||
return $aRes;
|
return $aRes;
|
||||||
}
|
}
|
||||||
@@ -809,20 +753,13 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
// Note: In most cases the object set is ignored because it was interesting to optimize for huge data sets
|
// Note: In most cases the object set is ignored because it was interesting to optimize for huge data sets
|
||||||
// and acceptable to consider only the root class of the object set
|
// and acceptable to consider only the root class of the object set
|
||||||
|
|
||||||
if ($iPermission != UR_ALLOWED_YES)
|
if ($iPermission != UR_ALLOWED_YES) {
|
||||||
{
|
|
||||||
// It is already NO for everyone... that's the final word!
|
// It is already NO for everyone... that's the final word!
|
||||||
}
|
} elseif ($iActionCode == UR_ACTION_READ) {
|
||||||
elseif ($iActionCode == UR_ACTION_READ)
|
|
||||||
{
|
|
||||||
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
||||||
}
|
} elseif ($iActionCode == UR_ACTION_BULK_READ) {
|
||||||
elseif ($iActionCode == UR_ACTION_BULK_READ)
|
|
||||||
{
|
|
||||||
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
||||||
}
|
} elseif ($oInstanceSet) {
|
||||||
elseif ($oInstanceSet)
|
|
||||||
{
|
|
||||||
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
// 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
|
// We have to answer NO for objects shared for reading purposes
|
||||||
if (self::HasSharing() && SharedObject::GetSharedClassProperties($sClass)) {
|
if (self::HasSharing() && SharedObject::GetSharedClassProperties($sClass)) {
|
||||||
@@ -886,8 +823,8 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
// Note: this code is VERY close to the code of IsActionAllowed()
|
// Note: this code is VERY close to the code of IsActionAllowed()
|
||||||
$iUser = $oUser->GetKey();
|
$iUser = $oUser->GetKey();
|
||||||
|
|
||||||
// Cache user's profiles
|
// Cache user's profiles
|
||||||
if(false === array_key_exists($iUser, $this->aUsersProfilesList)){
|
if (false === array_key_exists($iUser, $this->aUsersProfilesList)) {
|
||||||
$this->aUsersProfilesList[$iUser] = UserRights::ListProfiles($oUser);
|
$this->aUsersProfilesList[$iUser] = UserRights::ListProfiles($oUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -895,20 +832,14 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
// and acceptable to consider only the root class of the object set
|
// and acceptable to consider only the root class of the object set
|
||||||
$bStatus = null;
|
$bStatus = null;
|
||||||
// Call the API of UserRights because it caches the list for us
|
// Call the API of UserRights because it caches the list for us
|
||||||
foreach($this->aUsersProfilesList[$iUser] as $iProfile => $oProfile)
|
foreach ($this->aUsersProfilesList[$iUser] as $iProfile => $oProfile) {
|
||||||
{
|
|
||||||
$bGrant = $this->GetClassStimulusGrant($iProfile, $sClass, $sStimulusCode);
|
$bGrant = $this->GetClassStimulusGrant($iProfile, $sClass, $sStimulusCode);
|
||||||
if (!is_null($bGrant))
|
if (!is_null($bGrant)) {
|
||||||
{
|
if ($bGrant) {
|
||||||
if ($bGrant)
|
if (is_null($bStatus)) {
|
||||||
{
|
|
||||||
if (is_null($bStatus))
|
|
||||||
{
|
|
||||||
$bStatus = true;
|
$bStatus = true;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$bStatus = false;
|
$bStatus = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -932,22 +863,16 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
{
|
{
|
||||||
$sAttCode = null;
|
$sAttCode = null;
|
||||||
|
|
||||||
$aCallSpec = array($sClass, 'MapContextParam');
|
$aCallSpec = [$sClass, 'MapContextParam'];
|
||||||
if (($sClass == 'Organization') || is_subclass_of($sClass, 'Organization'))
|
if (($sClass == 'Organization') || is_subclass_of($sClass, 'Organization')) {
|
||||||
{
|
|
||||||
$sAttCode = 'id';
|
$sAttCode = 'id';
|
||||||
}
|
} elseif (is_callable($aCallSpec)) {
|
||||||
elseif (is_callable($aCallSpec))
|
|
||||||
{
|
|
||||||
$sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter
|
$sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter
|
||||||
if (!MetaModel::IsValidAttCode($sClass, $sAttCode))
|
if (!MetaModel::IsValidAttCode($sClass, $sAttCode)) {
|
||||||
{
|
|
||||||
// Skip silently. The data model checker will tell you something about this...
|
// Skip silently. The data model checker will tell you something about this...
|
||||||
$sAttCode = null;
|
$sAttCode = null;
|
||||||
}
|
}
|
||||||
}
|
} elseif (MetaModel::IsValidAttCode($sClass, 'org_id')) {
|
||||||
elseif(MetaModel::IsValidAttCode($sClass, 'org_id'))
|
|
||||||
{
|
|
||||||
$sAttCode = 'org_id';
|
$sAttCode = 'org_id';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -960,14 +885,11 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
protected static function HasSharing()
|
protected static function HasSharing()
|
||||||
{
|
{
|
||||||
static $bHasSharing;
|
static $bHasSharing;
|
||||||
if (!isset($bHasSharing))
|
if (!isset($bHasSharing)) {
|
||||||
{
|
|
||||||
$bHasSharing = class_exists('SharedObject');
|
$bHasSharing = class_exists('SharedObject');
|
||||||
}
|
}
|
||||||
return $bHasSharing;
|
return $bHasSharing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
UserRights::SelectModule('UserRightsProfile');
|
UserRights::SelectModule('UserRightsProfile');
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
3
app.php
3
app.php
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2024 Combodo SAS
|
* Copyright (C) 2013-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
@@ -25,5 +26,5 @@ require_once('approot.inc.php');
|
|||||||
require_once('application/startup.inc.php');
|
require_once('application/startup.inc.php');
|
||||||
|
|
||||||
return function (array $context) {
|
return function (array $context) {
|
||||||
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -48,8 +49,7 @@ class DBSearchHelper
|
|||||||
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW);
|
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW);
|
||||||
$oSearch->AddCondition_PointingTo($oHKFilter, $sAttCode);
|
$oSearch->AddCondition_PointingTo($oHKFilter, $sAttCode);
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e) {
|
|
||||||
// If filtering fails just ignore it
|
// If filtering fails just ignore it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,4 +57,4 @@ class DBSearchHelper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -16,10 +17,9 @@ use Combodo\iTop\Application\WebPage\AjaxPage;
|
|||||||
*/
|
*/
|
||||||
class ajax_page extends AjaxPage
|
class ajax_page extends AjaxPage
|
||||||
{
|
{
|
||||||
function __construct($s_title)
|
public function __construct($s_title)
|
||||||
{
|
{
|
||||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('ajax_page is deprecated. Please use AjaxPage instead');
|
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('ajax_page is deprecated. Please use AjaxPage instead');
|
||||||
parent::__construct($s_title);
|
parent::__construct($s_title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// 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
|
// 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
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ApplicationContext
|
* Class ApplicationContext
|
||||||
*
|
*
|
||||||
@@ -47,16 +47,16 @@ interface iDBObjectURLMaker
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Direct end-users to the standard iTop application: UI.php
|
* Direct end-users to the standard iTop application: UI.php
|
||||||
*/
|
*/
|
||||||
class iTopStandardURLMaker implements iDBObjectURLMaker
|
class iTopStandardURLMaker implements iDBObjectURLMaker
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param string $sClass
|
* @param string $sClass
|
||||||
* @param string $iId
|
* @param string $iId
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function MakeObjectURL($sClass, $iId)
|
public static function MakeObjectURL($sClass, $iId)
|
||||||
{
|
{
|
||||||
$sPage = DBObject::ComputeStandardUIPage($sClass);
|
$sPage = DBObject::ComputeStandardUIPage($sClass);
|
||||||
@@ -68,16 +68,16 @@ class iTopStandardURLMaker implements iDBObjectURLMaker
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Direct end-users to the standard Portal application
|
* Direct end-users to the standard Portal application
|
||||||
*/
|
*/
|
||||||
class PortalURLMaker implements iDBObjectURLMaker
|
class PortalURLMaker implements iDBObjectURLMaker
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param string $sClass
|
* @param string $sClass
|
||||||
* @param string $iId
|
* @param string $iId
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function MakeObjectURL($sClass, $iId)
|
public static function MakeObjectURL($sClass, $iId)
|
||||||
{
|
{
|
||||||
$sAbsoluteUrl = utils::GetAbsoluteUrlAppRoot();
|
$sAbsoluteUrl = utils::GetAbsoluteUrlAppRoot();
|
||||||
@@ -86,7 +86,6 @@ class PortalURLMaker implements iDBObjectURLMaker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to store and manipulate the parameters that make the application's context
|
* Helper class to store and manipulate the parameters that make the application's context
|
||||||
*
|
*
|
||||||
@@ -99,99 +98,90 @@ class PortalURLMaker implements iDBObjectURLMaker
|
|||||||
*/
|
*/
|
||||||
class ApplicationContext
|
class ApplicationContext
|
||||||
{
|
{
|
||||||
public static $m_sUrlMakerClass = null;
|
public static $m_sUrlMakerClass = null;
|
||||||
protected static $m_aPluginProperties = null;
|
protected static $m_aPluginProperties = null;
|
||||||
protected static $aDefaultValues; // Cache shared among all instances
|
protected static $aDefaultValues; // Cache shared among all instances
|
||||||
|
|
||||||
protected $aNames;
|
protected $aNames;
|
||||||
protected $aValues;
|
protected $aValues;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ApplicationContext constructor.
|
* ApplicationContext constructor.
|
||||||
*
|
*
|
||||||
* @param bool $bReadContext
|
* @param bool $bReadContext
|
||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function __construct($bReadContext = true)
|
public function __construct($bReadContext = true)
|
||||||
{
|
{
|
||||||
$this->aNames = array(
|
$this->aNames = [
|
||||||
'org_id', 'menu'
|
'org_id', 'menu',
|
||||||
);
|
];
|
||||||
if ($bReadContext)
|
if ($bReadContext) {
|
||||||
{
|
$this->ReadContext();
|
||||||
$this->ReadContext();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the context directly in the PHP parameters (either POST or GET)
|
* Read the context directly in the PHP parameters (either POST or GET)
|
||||||
* return nothing
|
* return nothing
|
||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
protected function ReadContext()
|
protected function ReadContext()
|
||||||
{
|
{
|
||||||
if (!isset(self::$aDefaultValues))
|
if (!isset(self::$aDefaultValues)) {
|
||||||
{
|
self::$aDefaultValues = [];
|
||||||
self::$aDefaultValues = array();
|
$aContext = utils::ReadParam('c', [], false, 'context_param');
|
||||||
$aContext = utils::ReadParam('c', array(), false, 'context_param');
|
foreach ($this->aNames as $sName) {
|
||||||
foreach($this->aNames as $sName)
|
|
||||||
{
|
|
||||||
$sValue = isset($aContext[$sName]) ? $aContext[$sName] : '';
|
$sValue = isset($aContext[$sName]) ? $aContext[$sName] : '';
|
||||||
// TO DO: check if some of the context parameters are mandatory (or have default values)
|
// TO DO: check if some of the context parameters are mandatory (or have default values)
|
||||||
if (!empty($sValue))
|
if (!empty($sValue)) {
|
||||||
{
|
|
||||||
self::$aDefaultValues[$sName] = $sValue;
|
self::$aDefaultValues[$sName] = $sValue;
|
||||||
}
|
}
|
||||||
// Hmm, there must be a better (more generic) way to handle the case below:
|
// Hmm, there must be a better (more generic) way to handle the case below:
|
||||||
// When there is only one possible (allowed) organization, the context must be
|
// When there is only one possible (allowed) organization, the context must be
|
||||||
// fixed to this org unless there is only one organization in the system then
|
// fixed to this org unless there is only one organization in the system then
|
||||||
// no filter is applied
|
// no filter is applied
|
||||||
if ($sName == 'org_id')
|
if ($sName == 'org_id') {
|
||||||
{
|
if (MetaModel::IsValidClass('Organization')) {
|
||||||
if (MetaModel::IsValidClass('Organization'))
|
|
||||||
{
|
|
||||||
$oSearchFilter = new DBObjectSearch('Organization');
|
$oSearchFilter = new DBObjectSearch('Organization');
|
||||||
$oSet = new CMDBObjectSet($oSearchFilter);
|
$oSet = new CMDBObjectSet($oSearchFilter);
|
||||||
$iCount = $oSet->CountWithLimit(2);
|
$iCount = $oSet->CountWithLimit(2);
|
||||||
if ($iCount > 1)
|
if ($iCount > 1) {
|
||||||
{
|
|
||||||
$oSearchFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true);
|
$oSearchFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true);
|
||||||
$oSet = new CMDBObjectSet($oSearchFilter);
|
$oSet = new CMDBObjectSet($oSearchFilter);
|
||||||
$iCount = $oSet->CountWithLimit(2);
|
$iCount = $oSet->CountWithLimit(2);
|
||||||
if ($iCount == 1)
|
if ($iCount == 1) {
|
||||||
{
|
|
||||||
// Only one possible value for org_id, set it in the context
|
// Only one possible value for org_id, set it in the context
|
||||||
$oOrg = $oSet->Fetch();
|
$oOrg = $oSet->Fetch();
|
||||||
self::$aDefaultValues[$sName] = $oOrg->GetKey();
|
self::$aDefaultValues[$sName] = $oOrg->GetKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->aValues = self::$aDefaultValues;
|
$this->aValues = self::$aDefaultValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current value for the given parameter
|
* Returns the current value for the given parameter
|
||||||
*
|
*
|
||||||
* @param string $sParamName Name of the parameter to read
|
* @param string $sParamName Name of the parameter to read
|
||||||
* @param string $defaultValue
|
* @param string $defaultValue
|
||||||
*
|
*
|
||||||
* @return mixed The value for this parameter
|
* @return mixed The value for this parameter
|
||||||
*/
|
*/
|
||||||
public function GetCurrentValue($sParamName, $defaultValue = '')
|
public function GetCurrentValue($sParamName, $defaultValue = '')
|
||||||
{
|
{
|
||||||
if (isset($this->aValues[$sParamName]))
|
if (isset($this->aValues[$sParamName])) {
|
||||||
{
|
|
||||||
return $this->aValues[$sParamName];
|
return $this->aValues[$sParamName];
|
||||||
}
|
}
|
||||||
return $defaultValue;
|
return $defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the context as string with the format name1=value1&name2=value2....
|
* Returns the context as string with the format name1=value1&name2=value2....
|
||||||
* @return string The context as a string to be appended to an href property
|
* @return string The context as a string to be appended to an href property
|
||||||
@@ -200,21 +190,20 @@ class ApplicationContext
|
|||||||
public function GetForLink(bool $bWithLeadingAmpersand = false)
|
public function GetForLink(bool $bWithLeadingAmpersand = false)
|
||||||
{
|
{
|
||||||
// If there are no parameters, return an empty string
|
// If there are no parameters, return an empty string
|
||||||
if(empty($this->aValues)){
|
if (empty($this->aValues)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the query string with ampersand separated parameters
|
// Build the query string with ampersand separated parameters
|
||||||
$aParams = array();
|
$aParams = [];
|
||||||
foreach($this->aValues as $sName => $sValue)
|
foreach ($this->aValues as $sName => $sValue) {
|
||||||
{
|
|
||||||
$aParams[] = "c[$sName]".'='.urlencode($sValue);
|
$aParams[] = "c[$sName]".'='.urlencode($sValue);
|
||||||
}
|
}
|
||||||
$sReturnValue = implode('&', $aParams);
|
$sReturnValue = implode('&', $aParams);
|
||||||
|
|
||||||
// add the leading ampersand if requested
|
// add the leading ampersand if requested
|
||||||
if($bWithLeadingAmpersand){
|
if ($bWithLeadingAmpersand) {
|
||||||
$sReturnValue = '&' . $sReturnValue;
|
$sReturnValue = '&'.$sReturnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sReturnValue;
|
return $sReturnValue;
|
||||||
@@ -278,14 +267,13 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public function GetAsHash()
|
public function GetAsHash()
|
||||||
{
|
{
|
||||||
$aReturn = array();
|
$aReturn = [];
|
||||||
foreach($this->aValues as $sName => $sValue)
|
foreach ($this->aValues as $sName => $sValue) {
|
||||||
{
|
|
||||||
$aReturn["c[$sName]"] = $sValue;
|
$aReturn["c[$sName]"] = $sValue;
|
||||||
}
|
}
|
||||||
return $aReturn;
|
return $aReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of the context parameters NAMEs
|
* Returns an array of the context parameters NAMEs
|
||||||
* @return array The list of context parameters
|
* @return array The list of context parameters
|
||||||
@@ -298,11 +286,10 @@ class ApplicationContext
|
|||||||
* Removes the specified parameter from the context, for example when the same parameter
|
* Removes the specified parameter from the context, for example when the same parameter
|
||||||
* is already a search parameter
|
* is already a search parameter
|
||||||
* @param string $sParamName Name of the parameter to remove
|
* @param string $sParamName Name of the parameter to remove
|
||||||
*/
|
*/
|
||||||
public function Reset($sParamName)
|
public function Reset($sParamName)
|
||||||
{
|
{
|
||||||
if (isset($this->aValues[$sParamName]))
|
if (isset($this->aValues[$sParamName])) {
|
||||||
{
|
|
||||||
unset($this->aValues[$sParamName]);
|
unset($this->aValues[$sParamName]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -318,27 +305,22 @@ class ApplicationContext
|
|||||||
public function InitObjectFromContext(DBObject &$oObj)
|
public function InitObjectFromContext(DBObject &$oObj)
|
||||||
{
|
{
|
||||||
$sClass = get_class($oObj);
|
$sClass = get_class($oObj);
|
||||||
foreach($this->GetNames() as $key)
|
foreach ($this->GetNames() as $key) {
|
||||||
{
|
$aCallSpec = [$sClass, 'MapContextParam'];
|
||||||
$aCallSpec = array($sClass, 'MapContextParam');
|
if (is_callable($aCallSpec)) {
|
||||||
if (is_callable($aCallSpec))
|
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||||
{
|
|
||||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
|
||||||
|
|
||||||
if (MetaModel::IsValidAttCode($sClass, $sAttCode))
|
if (MetaModel::IsValidAttCode($sClass, $sAttCode)) {
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
if ($oAttDef->IsWritable())
|
if ($oAttDef->IsWritable()) {
|
||||||
{
|
|
||||||
$value = $this->GetCurrentValue($key, null);
|
$value = $this->GetCurrentValue($key, null);
|
||||||
if (!is_null($value))
|
if (!is_null($value)) {
|
||||||
{
|
|
||||||
$oObj->Set($sAttCode, $value);
|
$oObj->Set($sAttCode, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -362,14 +344,10 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public static function GetUrlMakerClass()
|
public static function GetUrlMakerClass()
|
||||||
{
|
{
|
||||||
if (is_null(self::$m_sUrlMakerClass))
|
if (is_null(self::$m_sUrlMakerClass)) {
|
||||||
{
|
if (Session::IsSet('UrlMakerClass')) {
|
||||||
if (Session::IsSet('UrlMakerClass'))
|
|
||||||
{
|
|
||||||
self::$m_sUrlMakerClass = Session::Get('UrlMakerClass');
|
self::$m_sUrlMakerClass = Session::Get('UrlMakerClass');
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
self::$m_sUrlMakerClass = 'iTopStandardURLMaker';
|
self::$m_sUrlMakerClass = 'iTopStandardURLMaker';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -387,23 +365,23 @@ class ApplicationContext
|
|||||||
* @return string the name of the class
|
* @return string the name of the class
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function MakeObjectUrl($sObjClass, $sObjKey, $sUrlMakerClass = null, $bWithNavigationContext = true)
|
public static function MakeObjectUrl($sObjClass, $sObjKey, $sUrlMakerClass = null, $bWithNavigationContext = true)
|
||||||
{
|
{
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
|
|
||||||
if (is_null($sUrlMakerClass)) {
|
if (is_null($sUrlMakerClass)) {
|
||||||
$sUrlMakerClass = self::GetUrlMakerClass();
|
$sUrlMakerClass = self::GetUrlMakerClass();
|
||||||
}
|
}
|
||||||
$sUrl = call_user_func(array($sUrlMakerClass, 'MakeObjectUrl'), $sObjClass, $sObjKey);
|
$sUrl = call_user_func([$sUrlMakerClass, 'MakeObjectUrl'], $sObjClass, $sObjKey);
|
||||||
if (utils::StrLen($sUrl) > 0) {
|
if (utils::StrLen($sUrl) > 0) {
|
||||||
if ($bWithNavigationContext) {
|
if ($bWithNavigationContext) {
|
||||||
return $sUrl.$oAppContext->GetForLink(true);
|
return $sUrl.$oAppContext->GetForLink(true);
|
||||||
} else {
|
} else {
|
||||||
return $sUrl;
|
return $sUrl;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -412,13 +390,10 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
protected static function LoadPluginProperties()
|
protected static function LoadPluginProperties()
|
||||||
{
|
{
|
||||||
if (Session::IsSet('PluginProperties'))
|
if (Session::IsSet('PluginProperties')) {
|
||||||
{
|
|
||||||
self::$m_aPluginProperties = Session::Get('PluginProperties');
|
self::$m_aPluginProperties = Session::Get('PluginProperties');
|
||||||
}
|
} else {
|
||||||
else
|
self::$m_aPluginProperties = [];
|
||||||
{
|
|
||||||
self::$m_aPluginProperties = array();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,7 +406,9 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public static function SetPluginProperty($sPluginClass, $sProperty, $value)
|
public static function SetPluginProperty($sPluginClass, $sProperty, $value)
|
||||||
{
|
{
|
||||||
if (is_null(self::$m_aPluginProperties)) self::LoadPluginProperties();
|
if (is_null(self::$m_aPluginProperties)) {
|
||||||
|
self::LoadPluginProperties();
|
||||||
|
}
|
||||||
|
|
||||||
self::$m_aPluginProperties[$sPluginClass][$sProperty] = $value;
|
self::$m_aPluginProperties[$sPluginClass][$sProperty] = $value;
|
||||||
Session::Set(['PluginProperties', $sPluginClass, $sProperty], $value);
|
Session::Set(['PluginProperties', $sPluginClass, $sProperty], $value);
|
||||||
@@ -444,15 +421,14 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public static function GetPluginProperties($sPluginClass)
|
public static function GetPluginProperties($sPluginClass)
|
||||||
{
|
{
|
||||||
if (is_null(self::$m_aPluginProperties)) self::LoadPluginProperties();
|
if (is_null(self::$m_aPluginProperties)) {
|
||||||
|
self::LoadPluginProperties();
|
||||||
if (array_key_exists($sPluginClass, self::$m_aPluginProperties))
|
|
||||||
{
|
|
||||||
return self::$m_aPluginProperties[$sPluginClass];
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
if (array_key_exists($sPluginClass, self::$m_aPluginProperties)) {
|
||||||
return array();
|
return self::$m_aPluginProperties[$sPluginClass];
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -524,7 +524,7 @@ abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
|
|||||||
*/
|
*/
|
||||||
public function EnumUsedAttributes($oObject)
|
public function EnumUsedAttributes($oObject)
|
||||||
{
|
{
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -548,7 +548,7 @@ abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
|
|||||||
*/
|
*/
|
||||||
public function EnumAllowedActions(DBObjectSet $oSet)
|
public function EnumAllowedActions(DBObjectSet $oSet)
|
||||||
{
|
{
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -686,7 +686,7 @@ abstract class AbstractApplicationObjectExtension implements iApplicationObjectE
|
|||||||
*/
|
*/
|
||||||
public function OnCheckToWrite($oObject)
|
public function OnCheckToWrite($oObject)
|
||||||
{
|
{
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -694,7 +694,7 @@ abstract class AbstractApplicationObjectExtension implements iApplicationObjectE
|
|||||||
*/
|
*/
|
||||||
public function OnCheckToDelete($oObject)
|
public function OnCheckToDelete($oObject)
|
||||||
{
|
{
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -739,21 +739,21 @@ interface iPopupMenuExtension
|
|||||||
* $param is a DBObjectSet containing the list of objects
|
* $param is a DBObjectSet containing the list of objects
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const MENU_OBJLIST_ACTIONS = 1;
|
public const MENU_OBJLIST_ACTIONS = 1;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Toolkit menu of a list
|
* Insert an item into the Toolkit menu of a list
|
||||||
*
|
*
|
||||||
* $param is a DBObjectSet containing the list of objects
|
* $param is a DBObjectSet containing the list of objects
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const MENU_OBJLIST_TOOLKIT = 2;
|
public const MENU_OBJLIST_TOOLKIT = 2;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Actions menu on an object details page
|
* Insert an item into the Actions menu on an object details page
|
||||||
*
|
*
|
||||||
* $param is a DBObject instance: the object currently displayed
|
* $param is a DBObject instance: the object currently displayed
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const MENU_OBJDETAILS_ACTIONS = 3;
|
public const MENU_OBJDETAILS_ACTIONS = 3;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Dashboard menu
|
* Insert an item into the Dashboard menu
|
||||||
*
|
*
|
||||||
@@ -763,14 +763,14 @@ interface iPopupMenuExtension
|
|||||||
* $param is a Dashboard instance: the dashboard currently displayed
|
* $param is a Dashboard instance: the dashboard currently displayed
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const MENU_DASHBOARD_ACTIONS = 4;
|
public const MENU_DASHBOARD_ACTIONS = 4;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the User menu (upper right corner)
|
* Insert an item into the User menu (upper right corner)
|
||||||
*
|
*
|
||||||
* $param is null
|
* $param is null
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const MENU_USER_ACTIONS = 5;
|
public const MENU_USER_ACTIONS = 5;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Action menu on an object item in an objects list in the portal
|
* Insert an item into the Action menu on an object item in an objects list in the portal
|
||||||
*
|
*
|
||||||
@@ -778,7 +778,7 @@ interface iPopupMenuExtension
|
|||||||
* the current line)
|
* the current line)
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const PORTAL_OBJLISTITEM_ACTIONS = 7;
|
public const PORTAL_OBJLISTITEM_ACTIONS = 7;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Action menu on an object details page in the portal
|
* Insert an item into the Action menu on an object details page in the portal
|
||||||
*
|
*
|
||||||
@@ -786,7 +786,7 @@ interface iPopupMenuExtension
|
|||||||
* currently displayed)
|
* currently displayed)
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const PORTAL_OBJDETAILS_ACTIONS = 8;
|
public const PORTAL_OBJDETAILS_ACTIONS = 8;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Actions menu of a list in the portal
|
* Insert an item into the Actions menu of a list in the portal
|
||||||
@@ -796,7 +796,7 @@ interface iPopupMenuExtension
|
|||||||
*
|
*
|
||||||
* @todo
|
* @todo
|
||||||
*/
|
*/
|
||||||
const PORTAL_OBJLIST_ACTIONS = 6;
|
public const PORTAL_OBJLIST_ACTIONS = 6;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the user menu of the portal
|
* Insert an item into the user menu of the portal
|
||||||
* Note: This is not implemented yet !
|
* Note: This is not implemented yet !
|
||||||
@@ -805,7 +805,7 @@ interface iPopupMenuExtension
|
|||||||
*
|
*
|
||||||
* @todo
|
* @todo
|
||||||
*/
|
*/
|
||||||
const PORTAL_USER_ACTIONS = 9;
|
public const PORTAL_USER_ACTIONS = 9;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the navigation menu of the portal
|
* Insert an item into the navigation menu of the portal
|
||||||
* Note: This is not implemented yet !
|
* Note: This is not implemented yet !
|
||||||
@@ -814,7 +814,7 @@ interface iPopupMenuExtension
|
|||||||
*
|
*
|
||||||
* @todo
|
* @todo
|
||||||
*/
|
*/
|
||||||
const PORTAL_MENU_ACTIONS = 10;
|
public const PORTAL_MENU_ACTIONS = 10;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of items to be added to a menu.
|
* Get the list of items to be added to a menu.
|
||||||
@@ -864,7 +864,7 @@ abstract class ApplicationPopupMenuItem
|
|||||||
$this->sLabel = $sLabel;
|
$this->sLabel = $sLabel;
|
||||||
$this->sTooltip = '';
|
$this->sTooltip = '';
|
||||||
$this->sIconClass = '';
|
$this->sIconClass = '';
|
||||||
$this->aCssClasses = array();
|
$this->aCssClasses = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -920,7 +920,6 @@ abstract class ApplicationPopupMenuItem
|
|||||||
$this->aCssClasses[] = $sCssClass;
|
$this->aCssClasses[] = $sCssClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $sTooltip
|
* @param $sTooltip
|
||||||
*
|
*
|
||||||
@@ -976,7 +975,7 @@ abstract class ApplicationPopupMenuItem
|
|||||||
/** @ignore */
|
/** @ignore */
|
||||||
public function GetLinkedScripts()
|
public function GetLinkedScripts()
|
||||||
{
|
{
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1015,13 +1014,13 @@ class URLPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
/** @ignore */
|
/** @ignore */
|
||||||
public function GetMenuItem()
|
public function GetMenuItem()
|
||||||
{
|
{
|
||||||
return array('label' => $this->GetLabel(),
|
return ['label' => $this->GetLabel(),
|
||||||
'url' => $this->GetUrl(),
|
'url' => $this->GetUrl(),
|
||||||
'target' => $this-> GetTarget(),
|
'target' => $this-> GetTarget(),
|
||||||
'css_classes' => $this->aCssClasses,
|
'css_classes' => $this->aCssClasses,
|
||||||
'icon_class' => $this->sIconClass,
|
'icon_class' => $this->sIconClass,
|
||||||
'tooltip' => $this->sTooltip
|
'tooltip' => $this->sTooltip,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
@@ -1065,7 +1064,7 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
* ans $sTarget will be ignored
|
* ans $sTarget will be ignored
|
||||||
* @param array $aIncludeJSFiles An array of file URLs to be included (once) to provide some JS libraries for the page.
|
* @param array $aIncludeJSFiles An array of file URLs to be included (once) to provide some JS libraries for the page.
|
||||||
*/
|
*/
|
||||||
public function __construct($sUID, $sLabel, $sJSCode, $aIncludeJSFiles = array())
|
public function __construct($sUID, $sLabel, $sJSCode, $aIncludeJSFiles = [])
|
||||||
{
|
{
|
||||||
parent::__construct($sUID, $sLabel);
|
parent::__construct($sUID, $sLabel);
|
||||||
$this->sJsCode = $sJSCode;
|
$this->sJsCode = $sJSCode;
|
||||||
@@ -1077,14 +1076,14 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
public function GetMenuItem()
|
public function GetMenuItem()
|
||||||
{
|
{
|
||||||
// Note: the semicolumn is a must here!
|
// Note: the semicolumn is a must here!
|
||||||
return array(
|
return [
|
||||||
'label' => $this->GetLabel(),
|
'label' => $this->GetLabel(),
|
||||||
'onclick' => $this->GetJsCode().'; return false;',
|
'onclick' => $this->GetJsCode().'; return false;',
|
||||||
'url' => $this->GetUrl(),
|
'url' => $this->GetUrl(),
|
||||||
'css_classes' => $this->GetCssClasses(),
|
'css_classes' => $this->GetCssClasses(),
|
||||||
'icon_class' => $this->sIconClass,
|
'icon_class' => $this->sIconClass,
|
||||||
'tooltip' => $this->sTooltip
|
'tooltip' => $this->sTooltip,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
@@ -1116,7 +1115,7 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
*/
|
*/
|
||||||
class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
||||||
{
|
{
|
||||||
static $idx = 0;
|
public static $idx = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
@@ -1130,7 +1129,7 @@ class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
/** @ignore */
|
/** @ignore */
|
||||||
public function GetMenuItem()
|
public function GetMenuItem()
|
||||||
{
|
{
|
||||||
return array('label' => '<hr class="menu-separator">', 'url' => '', 'css_classes' => $this->aCssClasses);
|
return ['label' => '<hr class="menu-separator">', 'url' => '', 'css_classes' => $this->aCssClasses];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1143,7 +1142,6 @@ class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
*/
|
*/
|
||||||
class URLButtonItem extends URLPopupMenuItem
|
class URLButtonItem extends URLPopupMenuItem
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1155,7 +1153,6 @@ class URLButtonItem extends URLPopupMenuItem
|
|||||||
*/
|
*/
|
||||||
class JSButtonItem extends JSPopupMenuItem
|
class JSButtonItem extends JSPopupMenuItem
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1504,9 +1501,9 @@ interface iBackofficeDictEntriesPrefixesExtension
|
|||||||
*/
|
*/
|
||||||
interface iPortalUIExtension
|
interface iPortalUIExtension
|
||||||
{
|
{
|
||||||
const ENUM_PORTAL_EXT_UI_BODY = 'Body';
|
public const ENUM_PORTAL_EXT_UI_BODY = 'Body';
|
||||||
const ENUM_PORTAL_EXT_UI_NAVIGATION_MENU = 'NavigationMenu';
|
public const ENUM_PORTAL_EXT_UI_NAVIGATION_MENU = 'NavigationMenu';
|
||||||
const ENUM_PORTAL_EXT_UI_MAIN_CONTENT = 'MainContent';
|
public const ENUM_PORTAL_EXT_UI_MAIN_CONTENT = 'MainContent';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of CSS file urls
|
* Returns an array of CSS file urls
|
||||||
@@ -1593,7 +1590,7 @@ abstract class AbstractPortalUIExtension implements iPortalUIExtension
|
|||||||
*/
|
*/
|
||||||
public function GetCSSFiles(Container $oContainer)
|
public function GetCSSFiles(Container $oContainer)
|
||||||
{
|
{
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1609,7 +1606,7 @@ abstract class AbstractPortalUIExtension implements iPortalUIExtension
|
|||||||
*/
|
*/
|
||||||
public function GetJSFiles(Container $oContainer)
|
public function GetJSFiles(Container $oContainer)
|
||||||
{
|
{
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1729,62 +1726,62 @@ class RestResult
|
|||||||
* Result: no issue has been encountered
|
* Result: no issue has been encountered
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const OK = 0;
|
public const OK = 0;
|
||||||
/**
|
/**
|
||||||
* Result: missing/wrong credentials or the user does not have enough rights to perform the requested operation
|
* Result: missing/wrong credentials or the user does not have enough rights to perform the requested operation
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const UNAUTHORIZED = 1;
|
public const UNAUTHORIZED = 1;
|
||||||
/**
|
/**
|
||||||
* Result: the parameter 'version' is missing
|
* Result: the parameter 'version' is missing
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const MISSING_VERSION = 2;
|
public const MISSING_VERSION = 2;
|
||||||
/**
|
/**
|
||||||
* Result: the parameter 'json_data' is missing
|
* Result: the parameter 'json_data' is missing
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const MISSING_JSON = 3;
|
public const MISSING_JSON = 3;
|
||||||
/**
|
/**
|
||||||
* Result: the input structure is not a valid JSON string
|
* Result: the input structure is not a valid JSON string
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const INVALID_JSON = 4;
|
public const INVALID_JSON = 4;
|
||||||
/**
|
/**
|
||||||
* Result: the parameter 'auth_user' is missing, authentication aborted
|
* Result: the parameter 'auth_user' is missing, authentication aborted
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const MISSING_AUTH_USER = 5;
|
public const MISSING_AUTH_USER = 5;
|
||||||
/**
|
/**
|
||||||
* Result: the parameter 'auth_pwd' is missing, authentication aborted
|
* Result: the parameter 'auth_pwd' is missing, authentication aborted
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const MISSING_AUTH_PWD = 6;
|
public const MISSING_AUTH_PWD = 6;
|
||||||
/**
|
/**
|
||||||
* Result: no operation is available for the specified version
|
* Result: no operation is available for the specified version
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const UNSUPPORTED_VERSION = 10;
|
public const UNSUPPORTED_VERSION = 10;
|
||||||
/**
|
/**
|
||||||
* Result: the requested operation is not valid for the specified version
|
* Result: the requested operation is not valid for the specified version
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const UNKNOWN_OPERATION = 11;
|
public const UNKNOWN_OPERATION = 11;
|
||||||
/**
|
/**
|
||||||
* Result: the requested operation cannot be performed because it can cause data (integrity) loss
|
* Result: the requested operation cannot be performed because it can cause data (integrity) loss
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const UNSAFE = 12;
|
public const UNSAFE = 12;
|
||||||
/**
|
/**
|
||||||
* Result: the request page number is not valid. It must be an integer greater than 0
|
* Result: the request page number is not valid. It must be an integer greater than 0
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const INVALID_PAGE = 13;
|
public const INVALID_PAGE = 13;
|
||||||
/**
|
/**
|
||||||
* Result: the operation could not be performed, see the message for troubleshooting
|
* Result: the operation could not be performed, see the message for troubleshooting
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
const INTERNAL_ERROR = 100;
|
public const INTERNAL_ERROR = 100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor - ok!
|
* Default constructor - ok!
|
||||||
@@ -1807,7 +1804,7 @@ class RestResult
|
|||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public $message;
|
public $message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sanitize the content of this result to hide sensitive information
|
* Sanitize the content of this result to hide sensitive information
|
||||||
*/
|
*/
|
||||||
@@ -1854,17 +1851,13 @@ class RestUtils
|
|||||||
*/
|
*/
|
||||||
public static function GetMandatoryParam($oData, $sParamName)
|
public static function GetMandatoryParam($oData, $sParamName)
|
||||||
{
|
{
|
||||||
if (isset($oData->$sParamName))
|
if (isset($oData->$sParamName)) {
|
||||||
{
|
|
||||||
return $oData->$sParamName;
|
return $oData->$sParamName;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new Exception("Missing parameter '$sParamName'");
|
throw new Exception("Missing parameter '$sParamName'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read an optional parameter from a Rest/Json structure.
|
* Read an optional parameter from a Rest/Json structure.
|
||||||
*
|
*
|
||||||
@@ -1879,17 +1872,13 @@ class RestUtils
|
|||||||
*/
|
*/
|
||||||
public static function GetOptionalParam($oData, $sParamName, $default)
|
public static function GetOptionalParam($oData, $sParamName, $default)
|
||||||
{
|
{
|
||||||
if (isset($oData->$sParamName))
|
if (isset($oData->$sParamName)) {
|
||||||
{
|
|
||||||
return $oData->$sParamName;
|
return $oData->$sParamName;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return $default;
|
return $default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a class from a Rest/Json structure.
|
* Read a class from a Rest/Json structure.
|
||||||
*
|
*
|
||||||
@@ -1903,15 +1892,13 @@ class RestUtils
|
|||||||
public static function GetClass($oData, $sParamName)
|
public static function GetClass($oData, $sParamName)
|
||||||
{
|
{
|
||||||
$sClass = self::GetMandatoryParam($oData, $sParamName);
|
$sClass = self::GetMandatoryParam($oData, $sParamName);
|
||||||
if (!MetaModel::IsValidClass($sClass))
|
if (!MetaModel::IsValidClass($sClass)) {
|
||||||
{
|
|
||||||
throw new Exception("$sParamName: '$sClass' is not a valid class'");
|
throw new Exception("$sParamName: '$sClass' is not a valid class'");
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sClass;
|
return $sClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a list of attribute codes from a Rest/Json structure.
|
* Read a list of attribute codes from a Rest/Json structure.
|
||||||
*
|
*
|
||||||
@@ -1927,31 +1914,21 @@ class RestUtils
|
|||||||
public static function GetFieldList($sClass, $oData, $sParamName)
|
public static function GetFieldList($sClass, $oData, $sParamName)
|
||||||
{
|
{
|
||||||
$sFields = self::GetOptionalParam($oData, $sParamName, '*');
|
$sFields = self::GetOptionalParam($oData, $sParamName, '*');
|
||||||
$aShowFields = array();
|
$aShowFields = [];
|
||||||
if ($sFields == '*')
|
if ($sFields == '*') {
|
||||||
{
|
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
|
||||||
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
|
|
||||||
{
|
|
||||||
$aShowFields[$sClass][] = $sAttCode;
|
$aShowFields[$sClass][] = $sAttCode;
|
||||||
}
|
}
|
||||||
}
|
} elseif ($sFields == '*+') {
|
||||||
elseif ($sFields == '*+')
|
foreach (MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL) as $sRefClass) {
|
||||||
{
|
foreach (MetaModel::ListAttributeDefs($sRefClass) as $sAttCode => $oAttDef) {
|
||||||
foreach (MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL) as $sRefClass)
|
|
||||||
{
|
|
||||||
foreach (MetaModel::ListAttributeDefs($sRefClass) as $sAttCode => $oAttDef)
|
|
||||||
{
|
|
||||||
$aShowFields[$sRefClass][] = $sAttCode;
|
$aShowFields[$sRefClass][] = $sAttCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
foreach (explode(',', $sFields) as $sAttCode) {
|
||||||
{
|
|
||||||
foreach (explode(',', $sFields) as $sAttCode)
|
|
||||||
{
|
|
||||||
$sAttCode = trim($sAttCode);
|
$sAttCode = trim($sAttCode);
|
||||||
if (($sAttCode != 'id') && (!MetaModel::IsValidAttCode($sClass, $sAttCode)))
|
if (($sAttCode != 'id') && (!MetaModel::IsValidAttCode($sClass, $sAttCode))) {
|
||||||
{
|
|
||||||
throw new Exception("$sParamName: invalid attribute code '$sAttCode'");
|
throw new Exception("$sParamName: invalid attribute code '$sAttCode'");
|
||||||
}
|
}
|
||||||
$aShowFields[$sClass][] = $sAttCode;
|
$aShowFields[$sClass][] = $sAttCode;
|
||||||
@@ -1974,38 +1951,30 @@ class RestUtils
|
|||||||
*/
|
*/
|
||||||
protected static function FindObjectFromCriteria($sClass, $oCriteria)
|
protected static function FindObjectFromCriteria($sClass, $oCriteria)
|
||||||
{
|
{
|
||||||
$aCriteriaReport = array();
|
$aCriteriaReport = [];
|
||||||
if (isset($oCriteria->finalclass))
|
if (isset($oCriteria->finalclass)) {
|
||||||
{
|
if (!MetaModel::IsValidClass($oCriteria->finalclass)) {
|
||||||
if (!MetaModel::IsValidClass($oCriteria->finalclass))
|
|
||||||
{
|
|
||||||
throw new Exception("finalclass: Unknown class '".$oCriteria->finalclass."'");
|
throw new Exception("finalclass: Unknown class '".$oCriteria->finalclass."'");
|
||||||
}
|
}
|
||||||
if (!MetaModel::IsParentClass($sClass, $oCriteria->finalclass))
|
if (!MetaModel::IsParentClass($sClass, $oCriteria->finalclass)) {
|
||||||
{
|
|
||||||
throw new Exception("finalclass: '".$oCriteria->finalclass."' is not a child class of '$sClass'");
|
throw new Exception("finalclass: '".$oCriteria->finalclass."' is not a child class of '$sClass'");
|
||||||
}
|
}
|
||||||
$sClass = $oCriteria->finalclass;
|
$sClass = $oCriteria->finalclass;
|
||||||
}
|
}
|
||||||
$oSearch = new DBObjectSearch($sClass);
|
$oSearch = new DBObjectSearch($sClass);
|
||||||
foreach ($oCriteria as $sAttCode => $value)
|
foreach ($oCriteria as $sAttCode => $value) {
|
||||||
{
|
|
||||||
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
||||||
$oSearch->AddCondition($sAttCode, $realValue, '=');
|
$oSearch->AddCondition($sAttCode, $realValue, '=');
|
||||||
if (is_object($value) || is_array($value))
|
if (is_object($value) || is_array($value)) {
|
||||||
{
|
|
||||||
$value = json_encode($value);
|
$value = json_encode($value);
|
||||||
}
|
}
|
||||||
$aCriteriaReport[] = "$sAttCode: $value ($realValue)";
|
$aCriteriaReport[] = "$sAttCode: $value ($realValue)";
|
||||||
}
|
}
|
||||||
$oSet = new DBObjectSet($oSearch);
|
$oSet = new DBObjectSet($oSearch);
|
||||||
$iCount = $oSet->Count();
|
$iCount = $oSet->Count();
|
||||||
if ($iCount == 0)
|
if ($iCount == 0) {
|
||||||
{
|
|
||||||
throw new Exception("No item found with criteria: ".implode(', ', $aCriteriaReport));
|
throw new Exception("No item found with criteria: ".implode(', ', $aCriteriaReport));
|
||||||
}
|
} elseif ($iCount > 1) {
|
||||||
elseif ($iCount > 1)
|
|
||||||
{
|
|
||||||
throw new Exception("Several items found ($iCount) with criteria: ".implode(', ', $aCriteriaReport));
|
throw new Exception("Several items found ($iCount) with criteria: ".implode(', ', $aCriteriaReport));
|
||||||
}
|
}
|
||||||
$res = $oSet->Fetch();
|
$res = $oSet->Fetch();
|
||||||
@@ -2013,7 +1982,6 @@ class RestUtils
|
|||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find an object from a polymorph search specification (Rest/Json)
|
* Find an object from a polymorph search specification (Rest/Json)
|
||||||
*
|
*
|
||||||
@@ -2029,43 +1997,29 @@ class RestUtils
|
|||||||
*/
|
*/
|
||||||
public static function FindObjectFromKey($sClass, $key, $bAllowNullValue = false)
|
public static function FindObjectFromKey($sClass, $key, $bAllowNullValue = false)
|
||||||
{
|
{
|
||||||
if (is_object($key))
|
if (is_object($key)) {
|
||||||
{
|
|
||||||
$res = static::FindObjectFromCriteria($sClass, $key);
|
$res = static::FindObjectFromCriteria($sClass, $key);
|
||||||
}
|
} elseif (is_numeric($key)) {
|
||||||
elseif (is_numeric($key))
|
if ($bAllowNullValue && ($key == 0)) {
|
||||||
{
|
|
||||||
if ($bAllowNullValue && ($key == 0))
|
|
||||||
{
|
|
||||||
$res = null;
|
$res = null;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$res = MetaModel::GetObject($sClass, $key, false);
|
$res = MetaModel::GetObject($sClass, $key, false);
|
||||||
if (is_null($res))
|
if (is_null($res)) {
|
||||||
{
|
|
||||||
throw new Exception("Invalid object $sClass::$key");
|
throw new Exception("Invalid object $sClass::$key");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} elseif (is_string($key)) {
|
||||||
elseif (is_string($key))
|
|
||||||
{
|
|
||||||
// OQL
|
// OQL
|
||||||
$oSearch = DBObjectSearch::FromOQL($key);
|
$oSearch = DBObjectSearch::FromOQL($key);
|
||||||
$oSet = new DBObjectSet($oSearch);
|
$oSet = new DBObjectSet($oSearch);
|
||||||
$iCount = $oSet->Count();
|
$iCount = $oSet->Count();
|
||||||
if ($iCount == 0)
|
if ($iCount == 0) {
|
||||||
{
|
|
||||||
throw new Exception("No item found for query: $key");
|
throw new Exception("No item found for query: $key");
|
||||||
}
|
} elseif ($iCount > 1) {
|
||||||
elseif ($iCount > 1)
|
|
||||||
{
|
|
||||||
throw new Exception("Several items found ($iCount) for query: $key");
|
throw new Exception("Several items found ($iCount) for query: $key");
|
||||||
}
|
}
|
||||||
$res = $oSet->Fetch();
|
$res = $oSet->Fetch();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new Exception("Wrong format for key");
|
throw new Exception("Wrong format for key");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2086,47 +2040,37 @@ class RestUtils
|
|||||||
*/
|
*/
|
||||||
public static function GetObjectSetFromKey($sClass, $key, $iLimit = 0, $iOffset = 0)
|
public static function GetObjectSetFromKey($sClass, $key, $iLimit = 0, $iOffset = 0)
|
||||||
{
|
{
|
||||||
if (is_object($key))
|
if (is_object($key)) {
|
||||||
{
|
if (isset($key->finalclass)) {
|
||||||
if (isset($key->finalclass))
|
|
||||||
{
|
|
||||||
$sClass = $key->finalclass;
|
$sClass = $key->finalclass;
|
||||||
if (!MetaModel::IsValidClass($sClass))
|
if (!MetaModel::IsValidClass($sClass)) {
|
||||||
{
|
|
||||||
throw new Exception("finalclass: Unknown class '$sClass'");
|
throw new Exception("finalclass: Unknown class '$sClass'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$oSearch = new DBObjectSearch($sClass);
|
$oSearch = new DBObjectSearch($sClass);
|
||||||
foreach ($key as $sAttCode => $value)
|
foreach ($key as $sAttCode => $value) {
|
||||||
{
|
|
||||||
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
||||||
$oSearch->AddCondition($sAttCode, $realValue, '=');
|
$oSearch->AddCondition($sAttCode, $realValue, '=');
|
||||||
}
|
}
|
||||||
}
|
} elseif (is_numeric($key)) {
|
||||||
elseif (is_numeric($key))
|
|
||||||
{
|
|
||||||
$oSearch = new DBObjectSearch($sClass);
|
$oSearch = new DBObjectSearch($sClass);
|
||||||
$oSearch->AddCondition('id', $key);
|
$oSearch->AddCondition('id', $key);
|
||||||
}
|
} elseif (is_string($key)) {
|
||||||
elseif (is_string($key))
|
|
||||||
{
|
|
||||||
// OQL
|
// OQL
|
||||||
try {
|
try {
|
||||||
$oSearch = DBObjectSearch::FromOQL($key);
|
$oSearch = DBObjectSearch::FromOQL($key);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
throw new CoreOqlException('Query failed to execute', [
|
throw new CoreOqlException('Query failed to execute', [
|
||||||
'query' => $key,
|
'query' => $key,
|
||||||
'exception_class' => get_class($e),
|
'exception_class' => get_class($e),
|
||||||
'exception_message' => $e->getMessage(),
|
'exception_message' => $e->getMessage(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new Exception("Wrong format for key");
|
throw new Exception("Wrong format for key");
|
||||||
}
|
}
|
||||||
$oObjectSet = new DBObjectSet($oSearch, array(), array(), null, $iLimit, $iOffset);
|
$oObjectSet = new DBObjectSet($oSearch, [], [], null, $iLimit, $iOffset);
|
||||||
|
|
||||||
return $oObjectSet;
|
return $oObjectSet;
|
||||||
}
|
}
|
||||||
@@ -2144,53 +2088,38 @@ class RestUtils
|
|||||||
*/
|
*/
|
||||||
public static function MakeValue($sClass, $sAttCode, $value)
|
public static function MakeValue($sClass, $sAttCode, $value)
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
if (!MetaModel::IsValidAttCode($sClass, $sAttCode)) {
|
||||||
if (!MetaModel::IsValidAttCode($sClass, $sAttCode))
|
|
||||||
{
|
|
||||||
throw new Exception("Unknown attribute");
|
throw new Exception("Unknown attribute");
|
||||||
}
|
}
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
if ($oAttDef instanceof AttributeExternalKey)
|
if ($oAttDef instanceof AttributeExternalKey) {
|
||||||
{
|
|
||||||
$oExtKeyObject = static::FindObjectFromKey($oAttDef->GetTargetClass(), $value, true /* allow null */);
|
$oExtKeyObject = static::FindObjectFromKey($oAttDef->GetTargetClass(), $value, true /* allow null */);
|
||||||
$value = ($oExtKeyObject != null) ? $oExtKeyObject->GetKey() : 0;
|
$value = ($oExtKeyObject != null) ? $oExtKeyObject->GetKey() : 0;
|
||||||
}
|
} elseif ($oAttDef instanceof AttributeLinkedSet) {
|
||||||
elseif ($oAttDef instanceof AttributeLinkedSet)
|
if (!is_array($value)) {
|
||||||
{
|
|
||||||
if (!is_array($value))
|
|
||||||
{
|
|
||||||
throw new Exception("A link set must be defined by an array of objects");
|
throw new Exception("A link set must be defined by an array of objects");
|
||||||
}
|
}
|
||||||
$sLnkClass = $oAttDef->GetLinkedClass();
|
$sLnkClass = $oAttDef->GetLinkedClass();
|
||||||
$aLinks = array();
|
$aLinks = [];
|
||||||
foreach ($value as $oValues)
|
foreach ($value as $oValues) {
|
||||||
{
|
|
||||||
$oLnk = static::MakeObjectFromFields($sLnkClass, $oValues);
|
$oLnk = static::MakeObjectFromFields($sLnkClass, $oValues);
|
||||||
// Fix for N°1939
|
// Fix for N°1939
|
||||||
if (($oAttDef instanceof AttributeLinkedSetIndirect) && ($oLnk->Get($oAttDef->GetExtKeyToRemote()) == 0))
|
if (($oAttDef instanceof AttributeLinkedSetIndirect) && ($oLnk->Get($oAttDef->GetExtKeyToRemote()) == 0)) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$aLinks[] = $oLnk;
|
$aLinks[] = $oLnk;
|
||||||
}
|
}
|
||||||
$value = DBObjectSet::FromArray($sLnkClass, $aLinks);
|
$value = DBObjectSet::FromArray($sLnkClass, $aLinks);
|
||||||
}
|
} elseif ($oAttDef instanceof AttributeTagSet) {
|
||||||
elseif ($oAttDef instanceof AttributeTagSet)
|
if (!is_array($value)) {
|
||||||
{
|
|
||||||
if (!is_array($value))
|
|
||||||
{
|
|
||||||
throw new Exception("A tag set must be defined by an array of tag codes");
|
throw new Exception("A tag set must be defined by an array of tag codes");
|
||||||
}
|
}
|
||||||
$value = $oAttDef->FromJSONToValue($value);
|
$value = $oAttDef->FromJSONToValue($value);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$value = $oAttDef->FromJSONToValue($value);
|
$value = $oAttDef->FromJSONToValue($value);
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2210,15 +2139,11 @@ class RestUtils
|
|||||||
public static function MakeObjectFromFields($sClass, $aFields)
|
public static function MakeObjectFromFields($sClass, $aFields)
|
||||||
{
|
{
|
||||||
$oObject = MetaModel::NewObject($sClass);
|
$oObject = MetaModel::NewObject($sClass);
|
||||||
foreach ($aFields as $sAttCode => $value)
|
foreach ($aFields as $sAttCode => $value) {
|
||||||
{
|
|
||||||
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
$oObject->Set($sAttCode, $realValue);
|
$oObject->Set($sAttCode, $realValue);
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2239,15 +2164,11 @@ class RestUtils
|
|||||||
public static function UpdateObjectFromFields($oObject, $aFields)
|
public static function UpdateObjectFromFields($oObject, $aFields)
|
||||||
{
|
{
|
||||||
$sClass = get_class($oObject);
|
$sClass = get_class($oObject);
|
||||||
foreach ($aFields as $sAttCode => $value)
|
foreach ($aFields as $sAttCode => $value) {
|
||||||
{
|
|
||||||
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
$oObject->Set($sAttCode, $realValue);
|
$oObject->Set($sAttCode, $realValue);
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2256,7 +2177,6 @@ class RestUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helpers for modules extensibility, with discover performed by the MetaModel.
|
* Helpers for modules extensibility, with discover performed by the MetaModel.
|
||||||
*
|
*
|
||||||
@@ -2279,21 +2199,21 @@ interface iModuleExtension
|
|||||||
*/
|
*/
|
||||||
interface iKPILoggerExtension
|
interface iKPILoggerExtension
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Init the statistics collected
|
* Init the statistics collected
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function InitStats();
|
public function InitStats();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new KPI to the stats
|
* Add a new KPI to the stats
|
||||||
*
|
*
|
||||||
* @param \Combodo\iTop\Core\Kpi\KpiLogData $oKpiLogData
|
* @param \Combodo\iTop\Core\Kpi\KpiLogData $oKpiLogData
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function LogOperation($oKpiLogData);
|
public function LogOperation($oKpiLogData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2311,7 +2231,6 @@ interface iBackupExtraFilesExtension
|
|||||||
public function GetExtraFilesRelPaths(): array;
|
public function GetExtraFilesRelPaths(): array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to provide messages to be displayed in the "Welcome Popup"
|
* Interface to provide messages to be displayed in the "Welcome Popup"
|
||||||
*
|
*
|
||||||
@@ -2372,7 +2291,7 @@ abstract class AbstractWelcomePopupExtension implements iWelcomePopupExtension
|
|||||||
{
|
{
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
@@ -2381,4 +2300,4 @@ abstract class AbstractWelcomePopupExtension implements iWelcomePopupExtension
|
|||||||
// No need to process the acknowledgment notice by default
|
// No need to process the acknowledgment notice by default
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// 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
|
// 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
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class manages the audit "categories". Each category defines a set of objects
|
* This class manages the audit "categories". Each category defines a set of objects
|
||||||
* to check and is linked to a set of rules that determine the valid or invalid objects
|
* to check and is linked to a set of rules that determine the valid or invalid objects
|
||||||
@@ -32,34 +32,36 @@ class AuditCategory extends cmdbAbstractObject
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "application,grant_by_profile",
|
"category" => "application,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array('name'),
|
"reconc_keys" => ['name'],
|
||||||
"db_table" => "priv_auditcategory",
|
"db_table" => "priv_auditcategory",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-folder.svg'),
|
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-folder.svg'),
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("description"=>"Short name for this category", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("name", ["description" => "Short name for this category", "allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
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 AttributeString("description", ["allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeOQL("definition_set", array("allowed_values"=>null, "sql"=>"definition_set", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeOQL("definition_set", ["allowed_values" => null, "sql" => "definition_set", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeLinkedSet("rules_list", array("linked_class"=>"AuditRule", "ext_key_to_me"=>"category_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array(), "edit_mode" => LINKSET_EDITMODE_INPLACE, "tracking_level" => LINKSET_TRACKING_ALL)));
|
MetaModel::Init_AddAttribute(new AttributeLinkedSet("rules_list", ["linked_class" => "AuditRule", "ext_key_to_me" => "category_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => [], "edit_mode" => LINKSET_EDITMODE_INPLACE, "tracking_level" => LINKSET_TRACKING_ALL]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeInteger("ok_error_tolerance", array("allowed_values"=>null, "sql"=>"ok_error_tolerance", "default_value"=>5, "is_null_allowed"=>true, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeInteger("ok_error_tolerance", ["allowed_values" => null, "sql" => "ok_error_tolerance", "default_value" => 5, "is_null_allowed" => true, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeInteger("warning_error_tolerance", array("allowed_values" => null, "sql" => "warning_error_tolerance", "default_value" => 25, "is_null_allowed" => true, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeInteger("warning_error_tolerance", ["allowed_values" => null, "sql" => "warning_error_tolerance", "default_value" => 25, "is_null_allowed" => true, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("domains_list",
|
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect(
|
||||||
array("linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "category_id", "ext_key_to_remote" => "domain_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => array(), "display_style" => 'property')));
|
"domains_list",
|
||||||
|
["linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "category_id", "ext_key_to_remote" => "domain_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => [], "display_style" => 'property']
|
||||||
|
));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'definition_set', 'ok_error_tolerance', 'warning_error_tolerance', 'rules_list', 'domains_list')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['name', 'description', 'definition_set', 'ok_error_tolerance', 'warning_error_tolerance', 'rules_list', 'domains_list']); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('description', )); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', ['description', ]); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'definition_set')); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', ['description', 'definition_set']); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('default_search', array('name', 'description')); // Criteria of the default search form
|
MetaModel::Init_SetZListItems('default_search', ['name', 'description']); // Criteria of the default search form
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,9 +76,9 @@ class AuditCategory extends cmdbAbstractObject
|
|||||||
public function GetReportColor($iTotal, $iErrors)
|
public function GetReportColor($iTotal, $iErrors)
|
||||||
{
|
{
|
||||||
$sResult = 'red';
|
$sResult = 'red';
|
||||||
if ( ($iTotal == 0) || ($iErrors / $iTotal) <= ($this->Get('ok_error_tolerance') / 100) ) {
|
if (($iTotal == 0) || ($iErrors / $iTotal) <= ($this->Get('ok_error_tolerance') / 100)) {
|
||||||
$sResult = 'green';
|
$sResult = 'green';
|
||||||
} else if (($iErrors / $iTotal) <= ($this->Get('warning_error_tolerance') / 100)) {
|
} elseif (($iErrors / $iTotal) <= ($this->Get('warning_error_tolerance') / 100)) {
|
||||||
$sResult = 'orange';
|
$sResult = 'orange';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,4 +95,3 @@ class AuditCategory extends cmdbAbstractObject
|
|||||||
return $aShortcutActions;
|
return $aShortcutActions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class manages the audit "categories". Each category defines a set of objects
|
* This class manages the audit "categories". Each category defines a set of objects
|
||||||
* to check and is linked to a set of rules that determine the valid or invalid objects
|
* to check and is linked to a set of rules that determine the valid or invalid objects
|
||||||
@@ -33,32 +33,34 @@ class AuditDomain extends cmdbAbstractObject
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "application,grant_by_profile",
|
"category" => "application,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"complementary_name_attcode" => array('description'),
|
"complementary_name_attcode" => ['description'],
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array('name'),
|
"reconc_keys" => ['name'],
|
||||||
"db_table" => "priv_auditdomain",
|
"db_table" => "priv_auditdomain",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-album.svg'),
|
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-album.svg'),
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("description" => "Short name for this category", "allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeString("name", ["description" => "Short name for this category", "allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
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 AttributeString("description", ["allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeImage("icon", array("is_null_allowed" => true, "depends_on" => array(), "display_max_width" => 96, "display_max_height" => 96, "storage_max_width" => 256, "storage_max_height" => 256, "default_image" => null, "always_load_in_tables" => false)));
|
MetaModel::Init_AddAttribute(new AttributeImage("icon", ["is_null_allowed" => true, "depends_on" => [], "display_max_width" => 96, "display_max_height" => 96, "storage_max_width" => 256, "storage_max_height" => 256, "default_image" => null, "always_load_in_tables" => false]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("categories_list",
|
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect(
|
||||||
array("linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "domain_id", "ext_key_to_remote" => "category_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => array())));
|
"categories_list",
|
||||||
|
["linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "domain_id", "ext_key_to_remote" => "category_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => []]
|
||||||
|
));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'icon', 'categories_list')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['name', 'description', 'icon', 'categories_list']); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('description',)); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', ['description',]); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('description')); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', ['description']); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('default_search', array('name', 'description')); // Criteria of the default search form
|
MetaModel::Init_SetZListItems('default_search', ['name', 'description']); // Criteria of the default search form
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function GetShortcutActions($sFinalClass)
|
public static function GetShortcutActions($sFinalClass)
|
||||||
@@ -84,40 +86,39 @@ class lnkAuditCategoryToAuditDomain extends cmdbAbstractObject
|
|||||||
*/
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "application,grant_by_profile",
|
"category" => "application,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "",
|
"name_attcode" => "",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array('category_id', 'domain_id'),
|
"reconc_keys" => ['category_id', 'domain_id'],
|
||||||
"db_table" => "priv_link_audit_category_domain",
|
"db_table" => "priv_link_audit_category_domain",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"is_link" => true,
|
"is_link" => true,
|
||||||
'uniqueness_rules' => array(
|
'uniqueness_rules' => [
|
||||||
'no_duplicate' => array(
|
'no_duplicate' => [
|
||||||
'attributes' => array(
|
'attributes' => [
|
||||||
0 => 'category_id',
|
0 => 'category_id',
|
||||||
1 => 'domain_id',
|
1 => 'domain_id',
|
||||||
),
|
],
|
||||||
'filter' => '',
|
'filter' => '',
|
||||||
'disabled' => false,
|
'disabled' => false,
|
||||||
'is_blocking' => true,
|
'is_blocking' => true,
|
||||||
),
|
],
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("targetclass" => "AuditCategory", "jointype" => '', "allowed_values" => null, "sql" => "category_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", ["targetclass" => "AuditCategory", "jointype" => '', "allowed_values" => null, "sql" => "category_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", array("allowed_values" => null, "extkey_attcode" => 'category_id', "target_attcode" => "name")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", ["allowed_values" => null, "extkey_attcode" => 'category_id', "target_attcode" => "name"]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("domain_id", array("targetclass" => "AuditDomain", "jointype" => '', "allowed_values" => null, "sql" => "domain_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("domain_id", ["targetclass" => "AuditDomain", "jointype" => '', "allowed_values" => null, "sql" => "domain_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("domain_name", array("allowed_values" => null, "extkey_attcode" => 'domain_id', "target_attcode" => "name")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("domain_name", ["allowed_values" => null, "extkey_attcode" => 'domain_id', "target_attcode" => "name"]));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('category_id', 'domain_id'));
|
MetaModel::Init_SetZListItems('details', ['category_id', 'domain_id']);
|
||||||
MetaModel::Init_SetZListItems('list', array('category_id', 'domain_id'));
|
MetaModel::Init_SetZListItems('list', ['category_id', 'domain_id']);
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('category_id', 'domain_id'));
|
MetaModel::Init_SetZListItems('standard_search', ['category_id', 'domain_id']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// 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
|
// 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
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class manages the audit "rule" linked to a given audit category.
|
* This class manages the audit "rule" linked to a given audit category.
|
||||||
* Each rule is based on an OQL expression that returns either the "good" objects
|
* Each rule is based on an OQL expression that returns either the "good" objects
|
||||||
@@ -33,35 +33,34 @@ class AuditRule extends cmdbAbstractObject
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "application,grant_by_profile",
|
"category" => "application,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array('name'),
|
"reconc_keys" => ['name'],
|
||||||
"db_table" => "priv_auditrule",
|
"db_table" => "priv_auditrule",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit.svg'),
|
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit.svg'),
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
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("name", ["allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
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 AttributeString("description", ["allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeOQL("query", array("allowed_values" => null, "sql" => "query", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeOQL("query", ["allowed_values" => null, "sql" => "query", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("valid_flag", array("allowed_values" => new ValueSetEnum('true,false'), "sql" => "valid_flag", "default_value" => "true", "is_null_allowed" => false, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeEnum("valid_flag", ["allowed_values" => new ValueSetEnum('true,false'), "sql" => "valid_flag", "default_value" => "true", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("allowed_values" => null, "sql" => "category_id", "targetclass" => "AuditCategory", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", ["allowed_values" => null, "sql" => "category_id", "targetclass" => "AuditCategory", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", array("allowed_values" => null, "extkey_attcode" => 'category_id', "target_attcode" => "name")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", ["allowed_values" => null, "extkey_attcode" => 'category_id', "target_attcode" => "name"]));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('category_id', 'name', 'description', 'query', 'valid_flag')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['category_id', 'name', 'description', 'query', 'valid_flag']); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('category_id', 'description', 'valid_flag')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', ['category_id', 'description', 'valid_flag']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('category_id', 'name', 'description', 'valid_flag', 'query')); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', ['category_id', 'name', 'description', 'valid_flag', 'query']); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('default_search', array('name', 'description', 'category_id')); // Criteria of the advanced search form
|
MetaModel::Init_SetZListItems('default_search', ['name', 'description', 'category_id']); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static function GetShortcutActions($sFinalClass)
|
public static function GetShortcutActions($sFinalClass)
|
||||||
{
|
{
|
||||||
$aShortcutActions = parent::GetShortcutActions($sFinalClass);
|
$aShortcutActions = parent::GetShortcutActions($sFinalClass);
|
||||||
@@ -72,4 +71,3 @@ class AuditRule extends cmdbAbstractObject
|
|||||||
return $aShortcutActions;
|
return $aShortcutActions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader');
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader');
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2024 Combodo SAS
|
* Copyright (C) 2013-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
@@ -32,7 +33,8 @@ class CompileCSSService
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function CompileCSSFromSASS($sSassContent, $aImportPaths = [], $aVariables = []){
|
public function CompileCSSFromSASS($sSassContent, $aImportPaths = [], $aVariables = [])
|
||||||
|
{
|
||||||
return utils::CompileCSSFromSASS($sSassContent, $aImportPaths, $aVariables);
|
return utils::CompileCSSFromSASS($sSassContent, $aImportPaths, $aVariables);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader');
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -53,7 +54,7 @@ abstract class Dashboard
|
|||||||
$this->sLayoutClass = 'DashboardLayoutOneCol';
|
$this->sLayoutClass = 'DashboardLayoutOneCol';
|
||||||
$this->bAutoReload = false;
|
$this->bAutoReload = false;
|
||||||
$this->iAutoReloadSec = MetaModel::GetConfig()->GetStandardReloadInterval();
|
$this->iAutoReloadSec = MetaModel::GetConfig()->GetStandardReloadInterval();
|
||||||
$this->aCells = array();
|
$this->aCells = [];
|
||||||
$this->oDOMNode = null;
|
$this->oDOMNode = null;
|
||||||
$this->sId = $sId;
|
$this->sId = $sId;
|
||||||
}
|
}
|
||||||
@@ -65,8 +66,8 @@ abstract class Dashboard
|
|||||||
*/
|
*/
|
||||||
public function FromXml($sXml)
|
public function FromXml($sXml)
|
||||||
{
|
{
|
||||||
$this->aCells = array(); // reset the content of the dashboard
|
$this->aCells = []; // reset the content of the dashboard
|
||||||
set_error_handler(array('Dashboard', 'ErrorHandler'));
|
set_error_handler(['Dashboard', 'ErrorHandler']);
|
||||||
$oDoc = new DOMDocument();
|
$oDoc = new DOMDocument();
|
||||||
$oDoc->loadXML($sXml);
|
$oDoc->loadXML($sXml);
|
||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
@@ -79,87 +80,69 @@ abstract class Dashboard
|
|||||||
public function FromDOMDocument(DOMDocument $oDoc)
|
public function FromDOMDocument(DOMDocument $oDoc)
|
||||||
{
|
{
|
||||||
$this->oDOMNode = $oDoc->getElementsByTagName('dashboard')->item(0);
|
$this->oDOMNode = $oDoc->getElementsByTagName('dashboard')->item(0);
|
||||||
|
|
||||||
if ($oLayoutNode = $this->oDOMNode->getElementsByTagName('layout')->item(0))
|
if ($oLayoutNode = $this->oDOMNode->getElementsByTagName('layout')->item(0)) {
|
||||||
{
|
|
||||||
$this->sLayoutClass = $oLayoutNode->textContent;
|
$this->sLayoutClass = $oLayoutNode->textContent;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->sLayoutClass = 'DashboardLayoutOneCol';
|
$this->sLayoutClass = 'DashboardLayoutOneCol';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($oTitleNode = $this->oDOMNode->getElementsByTagName('title')->item(0))
|
if ($oTitleNode = $this->oDOMNode->getElementsByTagName('title')->item(0)) {
|
||||||
{
|
|
||||||
$this->sTitle = $oTitleNode->textContent;
|
$this->sTitle = $oTitleNode->textContent;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->sTitle = '';
|
$this->sTitle = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->bAutoReload = false;
|
$this->bAutoReload = false;
|
||||||
$this->iAutoReloadSec = MetaModel::GetConfig()->GetStandardReloadInterval();
|
$this->iAutoReloadSec = MetaModel::GetConfig()->GetStandardReloadInterval();
|
||||||
if ($oAutoReloadNode = $this->oDOMNode->getElementsByTagName('auto_reload')->item(0))
|
if ($oAutoReloadNode = $this->oDOMNode->getElementsByTagName('auto_reload')->item(0)) {
|
||||||
{
|
if ($oAutoReloadEnabled = $oAutoReloadNode->getElementsByTagName('enabled')->item(0)) {
|
||||||
if ($oAutoReloadEnabled = $oAutoReloadNode->getElementsByTagName('enabled')->item(0))
|
|
||||||
{
|
|
||||||
$this->bAutoReload = ($oAutoReloadEnabled->textContent == 'true');
|
$this->bAutoReload = ($oAutoReloadEnabled->textContent == 'true');
|
||||||
}
|
}
|
||||||
if ($oAutoReloadInterval = $oAutoReloadNode->getElementsByTagName('interval')->item(0))
|
if ($oAutoReloadInterval = $oAutoReloadNode->getElementsByTagName('interval')->item(0)) {
|
||||||
{
|
|
||||||
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int)$oAutoReloadInterval->textContent);
|
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int)$oAutoReloadInterval->textContent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($oCellsNode = $this->oDOMNode->getElementsByTagName('cells')->item(0))
|
if ($oCellsNode = $this->oDOMNode->getElementsByTagName('cells')->item(0)) {
|
||||||
{
|
|
||||||
$oCellsList = $oCellsNode->getElementsByTagName('cell');
|
$oCellsList = $oCellsNode->getElementsByTagName('cell');
|
||||||
$aCellOrder = array();
|
$aCellOrder = [];
|
||||||
$iCellRank = 0;
|
$iCellRank = 0;
|
||||||
/** @var \DOMElement $oCellNode */
|
/** @var \DOMElement $oCellNode */
|
||||||
foreach($oCellsList as $oCellNode)
|
foreach ($oCellsList as $oCellNode) {
|
||||||
{
|
|
||||||
$oCellRank = $oCellNode->getElementsByTagName('rank')->item(0);
|
$oCellRank = $oCellNode->getElementsByTagName('rank')->item(0);
|
||||||
if ($oCellRank)
|
if ($oCellRank) {
|
||||||
{
|
|
||||||
$iCellRank = (float)$oCellRank->textContent;
|
$iCellRank = (float)$oCellRank->textContent;
|
||||||
}
|
}
|
||||||
$oDashletsNode = $oCellNode->getElementsByTagName('dashlets')->item(0);
|
$oDashletsNode = $oCellNode->getElementsByTagName('dashlets')->item(0);
|
||||||
{
|
{
|
||||||
$oDashletList = $oDashletsNode->getElementsByTagName('dashlet');
|
$oDashletList = $oDashletsNode->getElementsByTagName('dashlet');
|
||||||
$iRank = 0;
|
$iRank = 0;
|
||||||
$aDashletOrder = array();
|
$aDashletOrder = [];
|
||||||
/** @var \DOMElement $oDomNode */
|
/** @var \DOMElement $oDomNode */
|
||||||
foreach($oDashletList as $oDomNode)
|
foreach ($oDashletList as $oDomNode) {
|
||||||
{
|
|
||||||
$oRank = $oDomNode->getElementsByTagName('rank')->item(0);
|
$oRank = $oDomNode->getElementsByTagName('rank')->item(0);
|
||||||
if ($oRank)
|
if ($oRank) {
|
||||||
{
|
|
||||||
$iRank = (float)$oRank->textContent;
|
$iRank = (float)$oRank->textContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
$oNewDashlet = $this->InitDashletFromDOMNode($oDomNode);
|
$oNewDashlet = $this->InitDashletFromDOMNode($oDomNode);
|
||||||
$aDashletOrder[] = array('rank' => $iRank, 'dashlet' => $oNewDashlet);
|
$aDashletOrder[] = ['rank' => $iRank, 'dashlet' => $oNewDashlet];
|
||||||
}
|
}
|
||||||
usort($aDashletOrder, array(get_class($this), 'SortOnRank'));
|
usort($aDashletOrder, [get_class($this), 'SortOnRank']);
|
||||||
$aDashletList = array();
|
$aDashletList = [];
|
||||||
foreach($aDashletOrder as $aItem)
|
foreach ($aDashletOrder as $aItem) {
|
||||||
{
|
|
||||||
$aDashletList[] = $aItem['dashlet'];
|
$aDashletList[] = $aItem['dashlet'];
|
||||||
}
|
}
|
||||||
$aCellOrder[] = array('rank' => $iCellRank, 'dashlets' => $aDashletList);
|
$aCellOrder[] = ['rank' => $iCellRank, 'dashlets' => $aDashletList];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
usort($aCellOrder, array(get_class($this), 'SortOnRank'));
|
usort($aCellOrder, [get_class($this), 'SortOnRank']);
|
||||||
foreach($aCellOrder as $aItem)
|
foreach ($aCellOrder as $aItem) {
|
||||||
{
|
|
||||||
$this->aCells[] = $aItem['dashlets'];
|
$this->aCells[] = $aItem['dashlets'];
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
$this->aCells = [];
|
||||||
{
|
|
||||||
$this->aCells = array();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,20 +152,20 @@ abstract class Dashboard
|
|||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
protected function InitDashletFromDOMNode($oDomNode)
|
protected function InitDashletFromDOMNode($oDomNode)
|
||||||
{
|
{
|
||||||
$sId = $oDomNode->getAttribute('id');
|
$sId = $oDomNode->getAttribute('id');
|
||||||
|
|
||||||
$sDashletType = $oDomNode->getAttribute('xsi:type');
|
$sDashletType = $oDomNode->getAttribute('xsi:type');
|
||||||
|
|
||||||
// Test if dashlet can be instantiated, otherwise (uninstalled, broken, ...) we display a placeholder
|
// Test if dashlet can be instantiated, otherwise (uninstalled, broken, ...) we display a placeholder
|
||||||
$sClass = static::GetDashletClassFromType($sDashletType);
|
$sClass = static::GetDashletClassFromType($sDashletType);
|
||||||
/** @var \Dashlet $oNewDashlet */
|
/** @var \Dashlet $oNewDashlet */
|
||||||
$oNewDashlet = new $sClass($this->oMetaModel, $sId);
|
$oNewDashlet = new $sClass($this->oMetaModel, $sId);
|
||||||
$oNewDashlet->SetDashletType($sDashletType);
|
$oNewDashlet->SetDashletType($sDashletType);
|
||||||
$oNewDashlet->FromDOMNode($oDomNode);
|
$oNewDashlet->FromDOMNode($oDomNode);
|
||||||
|
|
||||||
return $oNewDashlet;
|
return $oNewDashlet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $aItem1
|
* @param array $aItem1
|
||||||
@@ -208,12 +191,9 @@ abstract class Dashboard
|
|||||||
*/
|
*/
|
||||||
public static function ErrorHandler($errno, $errstr, $errfile, $errline)
|
public static function ErrorHandler($errno, $errstr, $errfile, $errline)
|
||||||
{
|
{
|
||||||
if ($errno == E_WARNING && (substr_count($errstr,"DOMDocument::loadXML()")>0))
|
if ($errno == E_WARNING && (substr_count($errstr, "DOMDocument::loadXML()") > 0)) {
|
||||||
{
|
|
||||||
throw new DOMException($errstr);
|
throw new DOMException($errstr);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -231,7 +211,7 @@ abstract class Dashboard
|
|||||||
$oMainNode = $oDoc->createElement('dashboard');
|
$oMainNode = $oDoc->createElement('dashboard');
|
||||||
$oMainNode->setAttribute('xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance");
|
$oMainNode->setAttribute('xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance");
|
||||||
$oDoc->appendChild($oMainNode);
|
$oDoc->appendChild($oMainNode);
|
||||||
|
|
||||||
$this->ToDOMNode($oMainNode);
|
$this->ToDOMNode($oMainNode);
|
||||||
|
|
||||||
$sXml = $oDoc->saveXML();
|
$sXml = $oDoc->saveXML();
|
||||||
@@ -261,23 +241,21 @@ abstract class Dashboard
|
|||||||
|
|
||||||
$oCellsNode = $oDoc->createElement('cells');
|
$oCellsNode = $oDoc->createElement('cells');
|
||||||
$oDefinition->appendChild($oCellsNode);
|
$oDefinition->appendChild($oCellsNode);
|
||||||
|
|
||||||
$iCellRank = 0;
|
$iCellRank = 0;
|
||||||
foreach ($this->aCells as $aCell)
|
foreach ($this->aCells as $aCell) {
|
||||||
{
|
|
||||||
$oCellNode = $oDoc->createElement('cell');
|
$oCellNode = $oDoc->createElement('cell');
|
||||||
$oCellNode->setAttribute('id', $iCellRank);
|
$oCellNode->setAttribute('id', $iCellRank);
|
||||||
$oCellsNode->appendChild($oCellNode);
|
$oCellsNode->appendChild($oCellNode);
|
||||||
$oCellRank = $oDoc->createElement('rank', $iCellRank);
|
$oCellRank = $oDoc->createElement('rank', $iCellRank);
|
||||||
$oCellNode->appendChild($oCellRank);
|
$oCellNode->appendChild($oCellRank);
|
||||||
$iCellRank++;
|
$iCellRank++;
|
||||||
|
|
||||||
$iDashletRank = 0;
|
$iDashletRank = 0;
|
||||||
$oDashletsNode = $oDoc->createElement('dashlets');
|
$oDashletsNode = $oDoc->createElement('dashlets');
|
||||||
$oCellNode->appendChild($oDashletsNode);
|
$oCellNode->appendChild($oDashletsNode);
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
foreach ($aCell as $oDashlet)
|
foreach ($aCell as $oDashlet) {
|
||||||
{
|
|
||||||
$oNode = $oDoc->createElement('dashlet');
|
$oNode = $oDoc->createElement('dashlet');
|
||||||
$oDashletsNode->appendChild($oNode);
|
$oDashletsNode->appendChild($oNode);
|
||||||
$oNode->setAttribute('id', $oDashlet->GetID());
|
$oNode->setAttribute('id', $oDashlet->GetID());
|
||||||
@@ -299,18 +277,15 @@ abstract class Dashboard
|
|||||||
$this->sTitle = $aParams['title'];
|
$this->sTitle = $aParams['title'];
|
||||||
$this->bAutoReload = $aParams['auto_reload'] == 'true';
|
$this->bAutoReload = $aParams['auto_reload'] == 'true';
|
||||||
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int) $aParams['auto_reload_sec']);
|
$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 = [];
|
||||||
$aCellDashlets = array();
|
foreach ($aCell as $aDashletParams) {
|
||||||
foreach($aCell as $aDashletParams)
|
|
||||||
{
|
|
||||||
$sDashletClass = $aDashletParams['dashlet_class'];
|
$sDashletClass = $aDashletParams['dashlet_class'];
|
||||||
$sId = $aDashletParams['dashlet_id'];
|
$sId = $aDashletParams['dashlet_id'];
|
||||||
/** @var \Dashlet $oNewDashlet */
|
/** @var \Dashlet $oNewDashlet */
|
||||||
$oNewDashlet = new $sDashletClass($this->oMetaModel, $sId);
|
$oNewDashlet = new $sDashletClass($this->oMetaModel, $sId);
|
||||||
if (isset($aDashletParams['dashlet_type']))
|
if (isset($aDashletParams['dashlet_type'])) {
|
||||||
{
|
|
||||||
$oNewDashlet->SetDashletType($aDashletParams['dashlet_type']);
|
$oNewDashlet->SetDashletType($aDashletParams['dashlet_type']);
|
||||||
}
|
}
|
||||||
$oForm = $oNewDashlet->GetForm();
|
$oForm = $oNewDashlet->GetForm();
|
||||||
@@ -322,12 +297,12 @@ abstract class Dashboard
|
|||||||
}
|
}
|
||||||
$this->aCells[] = $aCellDashlets;
|
$this->aCells[] = $aCellDashlets;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Save()
|
public function Save()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -420,7 +395,7 @@ abstract class Dashboard
|
|||||||
{
|
{
|
||||||
$sId = $this->GetNewDashletId();
|
$sId = $this->GetNewDashletId();
|
||||||
$oDashlet->SetId($sId);
|
$oDashlet->SetId($sId);
|
||||||
$this->aCells[] = array($oDashlet);
|
$this->aCells[] = [$oDashlet];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -430,7 +405,7 @@ abstract class Dashboard
|
|||||||
* @throws \ReflectionException
|
* @throws \ReflectionException
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function RenderProperties($oPage, $aExtraParams = array())
|
public function RenderProperties($oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
// menu to pick a layout and edit other properties of the dashboard
|
// menu to pick a layout and edit other properties of the dashboard
|
||||||
$oPage->add('<div class="ui-widget-content ui-corner-all ibo-dashboard-editor--properties"><div class="ui-widget-header ui-corner-all ibo-dashboard-editor--properties-title">'.Dict::S('UI:DashboardEdit:Properties').'</div>');
|
$oPage->add('<div class="ui-widget-content ui-corner-all ibo-dashboard-editor--properties"><div class="ui-widget-header ui-corner-all ibo-dashboard-editor--properties-title">'.Dict::S('UI:DashboardEdit:Properties').'</div>');
|
||||||
@@ -442,7 +417,7 @@ abstract class Dashboard
|
|||||||
if (is_subclass_of($sLayoutClass, 'DashboardLayout')) {
|
if (is_subclass_of($sLayoutClass, 'DashboardLayout')) {
|
||||||
$oReflection = new ReflectionClass($sLayoutClass);
|
$oReflection = new ReflectionClass($sLayoutClass);
|
||||||
if (!$oReflection->isAbstract()) {
|
if (!$oReflection->isAbstract()) {
|
||||||
$aCallSpec = array($sLayoutClass, 'GetInfo');
|
$aCallSpec = [$sLayoutClass, 'GetInfo'];
|
||||||
$aInfo = call_user_func($aCallSpec);
|
$aInfo = call_user_func($aCallSpec);
|
||||||
$sChecked = ($this->sLayoutClass == $sLayoutClass) ? 'checked' : '';
|
$sChecked = ($this->sLayoutClass == $sLayoutClass) ? 'checked' : '';
|
||||||
$oPage->add('<input type="radio" name="layout_class" '.$sChecked.' value="'.$sLayoutClass.'" id="layout_'.$sLayoutClass.'"><label for="layout_'.$sLayoutClass.'"><img src="'.$sUrl.$aInfo['icon'].'" class="ibo-dashboard--properties--icon" data-role="ibo-dashboard--properties--icon"/></label>'); // title="" on either the img or the label does nothing !
|
$oPage->add('<input type="radio" name="layout_class" '.$sChecked.' value="'.$sLayoutClass.'" id="layout_'.$sLayoutClass.'"><label for="layout_'.$sLayoutClass.'"><img src="'.$sUrl.$aInfo['icon'].'" class="ibo-dashboard--properties--icon" data-role="ibo-dashboard--properties--icon"/></label>'); // title="" on either the img or the label does nothing !
|
||||||
@@ -466,7 +441,6 @@ abstract class Dashboard
|
|||||||
$oField->SetBoundaries(MetaModel::GetConfig()->Get('min_reload_interval'), null); // no upper limit
|
$oField->SetBoundaries(MetaModel::GetConfig()->Get('min_reload_interval'), null); // no upper limit
|
||||||
$oForm->AddField($oField);
|
$oForm->AddField($oField);
|
||||||
|
|
||||||
|
|
||||||
$this->SetFormParams($oForm, $aExtraParams);
|
$this->SetFormParams($oForm, $aExtraParams);
|
||||||
$oForm->RenderAsPropertySheet($oPage, false, '.itop-dashboard');
|
$oForm->RenderAsPropertySheet($oPage, false, '.itop-dashboard');
|
||||||
|
|
||||||
@@ -474,7 +448,7 @@ abstract class Dashboard
|
|||||||
|
|
||||||
$sRateTitle = addslashes(Dict::Format('UI:DashboardEdit:AutoReloadSec+', MetaModel::GetConfig()->Get('min_reload_interval')));
|
$sRateTitle = addslashes(Dict::Format('UI:DashboardEdit:AutoReloadSec+', MetaModel::GetConfig()->Get('min_reload_interval')));
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
// Note: the title gets deleted by the validation mechanism
|
// Note: the title gets deleted by the validation mechanism
|
||||||
$("#attr_auto_reload_sec").attr('data-tooltip-content', '$sRateTitle');
|
$("#attr_auto_reload_sec").attr('data-tooltip-content', '$sRateTitle');
|
||||||
CombodoTooltip.InitTooltipFromMarkup($("#attr_auto_reload_sec"));
|
CombodoTooltip.InitTooltipFromMarkup($("#attr_auto_reload_sec"));
|
||||||
@@ -522,7 +496,7 @@ EOF
|
|||||||
*
|
*
|
||||||
* @return \Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout
|
* @return \Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout
|
||||||
*/
|
*/
|
||||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array(), $bCanEdit = true)
|
public function Render($oPage, $bEditMode = false, $aExtraParams = [], $bCanEdit = true)
|
||||||
{
|
{
|
||||||
$aExtraParams['dashboard_div_id'] = utils::Sanitize($aExtraParams['dashboard_div_id'] ?? null, $this->GetId(), utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
$aExtraParams['dashboard_div_id'] = utils::Sanitize($aExtraParams['dashboard_div_id'] ?? null, $this->GetId(), utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
||||||
|
|
||||||
@@ -551,7 +525,8 @@ EOF
|
|||||||
|
|
||||||
$oToolbar->AddHtml($sHtml);
|
$oToolbar->AddHtml($sHtml);
|
||||||
} else {
|
} else {
|
||||||
$oPage->add_script(<<<JS
|
$oPage->add_script(
|
||||||
|
<<<JS
|
||||||
$(".ibo-top-bar--toolbar-dashboard-title").html("$sTitleForHTML").attr("title", $('<div>').html("$sTitleForHTML").text());
|
$(".ibo-top-bar--toolbar-dashboard-title").html("$sTitleForHTML").attr("title", $('<div>').html("$sTitleForHTML").text());
|
||||||
JS
|
JS
|
||||||
);
|
);
|
||||||
@@ -595,7 +570,7 @@ JS
|
|||||||
* @param WebPage $oPage
|
* @param WebPage $oPage
|
||||||
* @param array $aExtraParams
|
* @param array $aExtraParams
|
||||||
*/
|
*/
|
||||||
public function RenderDashletsProperties(WebPage $oPage, $aExtraParams = array())
|
public function RenderDashletsProperties(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
// Toolbox/palette to edit the properties of each dashlet
|
// Toolbox/palette to edit the properties of each dashlet
|
||||||
$oPage->add('<div class="ui-widget-content ui-corner-all ibo-dashlet--properties"><div class="ui-widget-header ui-corner-all ibo-dashlet--properties--title">'.Dict::S('UI:DashboardEdit:DashletProperties').'</div>');
|
$oPage->add('<div class="ui-widget-content ui-corner-all ibo-dashlet--properties"><div class="ui-widget-header ui-corner-all ibo-dashlet--properties--title">'.Dict::S('UI:DashboardEdit:DashletProperties').'</div>');
|
||||||
@@ -604,13 +579,10 @@ JS
|
|||||||
$oLayout = new $this->sLayoutClass();
|
$oLayout = new $this->sLayoutClass();
|
||||||
|
|
||||||
$oPage->add('<div id="dashlet_properties">');
|
$oPage->add('<div id="dashlet_properties">');
|
||||||
foreach($this->aCells as $iCellIdx => $aCell)
|
foreach ($this->aCells as $iCellIdx => $aCell) {
|
||||||
{
|
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
foreach($aCell as $oDashlet)
|
foreach ($aCell as $oDashlet) {
|
||||||
{
|
if ($oDashlet->IsVisible()) {
|
||||||
if ($oDashlet->IsVisible())
|
|
||||||
{
|
|
||||||
$oPage->add('<div class="dashlet_properties" id="dashlet_properties_'.$oDashlet->GetID().'" style="display:none">');
|
$oPage->add('<div class="dashlet_properties" id="dashlet_properties_'.$oDashlet->GetID().'" style="display:none">');
|
||||||
$oForm = $oDashlet->GetForm();
|
$oForm = $oDashlet->GetForm();
|
||||||
$this->SetFormParams($oForm, $aExtraParams);
|
$this->SetFormParams($oForm, $aExtraParams);
|
||||||
@@ -632,18 +604,17 @@ JS
|
|||||||
*/
|
*/
|
||||||
protected function GetAvailableDashlets()
|
protected function GetAvailableDashlets()
|
||||||
{
|
{
|
||||||
$aDashlets = array();
|
$aDashlets = [];
|
||||||
|
|
||||||
foreach( get_declared_classes() as $sDashletClass)
|
foreach (get_declared_classes() as $sDashletClass) {
|
||||||
{
|
|
||||||
// DashletUnknown is not among the selection as it is just a fallback for dashlets that can't instantiated.
|
// DashletUnknown is not among the selection as it is just a fallback for dashlets that can't instantiated.
|
||||||
if (is_subclass_of($sDashletClass, 'Dashlet') && !in_array($sDashletClass, array('DashletUnknown', 'DashletProxy'))) {
|
if (is_subclass_of($sDashletClass, 'Dashlet') && !in_array($sDashletClass, ['DashletUnknown', 'DashletProxy'])) {
|
||||||
$oReflection = new ReflectionClass($sDashletClass);
|
$oReflection = new ReflectionClass($sDashletClass);
|
||||||
if (!$oReflection->isAbstract()) {
|
if (!$oReflection->isAbstract()) {
|
||||||
$aCallSpec = array($sDashletClass, 'IsVisible');
|
$aCallSpec = [$sDashletClass, 'IsVisible'];
|
||||||
$bVisible = call_user_func($aCallSpec);
|
$bVisible = call_user_func($aCallSpec);
|
||||||
if ($bVisible) {
|
if ($bVisible) {
|
||||||
$aCallSpec = array($sDashletClass, 'GetInfo');
|
$aCallSpec = [$sDashletClass, 'GetInfo'];
|
||||||
$aInfo = call_user_func($aCallSpec);
|
$aInfo = call_user_func($aCallSpec);
|
||||||
$aDashlets[$sDashletClass] = $aInfo;
|
$aDashlets[$sDashletClass] = $aInfo;
|
||||||
}
|
}
|
||||||
@@ -660,11 +631,9 @@ JS
|
|||||||
protected function GetNewDashletId()
|
protected function GetNewDashletId()
|
||||||
{
|
{
|
||||||
$iNewId = 0;
|
$iNewId = 0;
|
||||||
foreach($this->aCells as $aDashlets)
|
foreach ($this->aCells as $aDashlets) {
|
||||||
{
|
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
foreach($aDashlets as $oDashlet)
|
foreach ($aDashlets as $oDashlet) {
|
||||||
{
|
|
||||||
$iNewId = max($iNewId, (int)$oDashlet->GetID());
|
$iNewId = max($iNewId, (int)$oDashlet->GetID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -681,15 +650,15 @@ JS
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
abstract protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = array());
|
abstract protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = []);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \DesignerForm $oForm
|
* @param \DesignerForm $oForm
|
||||||
* @param array $aExtraParams
|
* @param array $aExtraParams
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
abstract protected function SetFormParams($oForm, $aExtraParams = array());
|
abstract protected function SetFormParams($oForm, $aExtraParams = []);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $sType
|
* @param string $sType
|
||||||
@@ -699,8 +668,7 @@ JS
|
|||||||
*/
|
*/
|
||||||
public static function GetDashletClassFromType($sType, $oFactory = null)
|
public static function GetDashletClassFromType($sType, $oFactory = null)
|
||||||
{
|
{
|
||||||
if (is_subclass_of($sType, 'Dashlet'))
|
if (is_subclass_of($sType, 'Dashlet')) {
|
||||||
{
|
|
||||||
return $sType;
|
return $sType;
|
||||||
}
|
}
|
||||||
return 'DashletUnknown';
|
return 'DashletUnknown';
|
||||||
@@ -723,14 +691,12 @@ JS
|
|||||||
*/
|
*/
|
||||||
public static function GetDashletUniqueId($bIsCustomized, $sDashboardDivId, $iRow, $iCol, $sDashletOrigId)
|
public static function GetDashletUniqueId($bIsCustomized, $sDashboardDivId, $iRow, $iCol, $sDashletOrigId)
|
||||||
{
|
{
|
||||||
if(strpos($sDashletOrigId, '_ID_row') !== false)
|
if (strpos($sDashletOrigId, '_ID_row') !== false) {
|
||||||
{
|
|
||||||
return $sDashletOrigId;
|
return $sDashletOrigId;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sDashletId = $sDashboardDivId."_ID_row".$iRow."_col".$iCol."_".$sDashletOrigId;
|
$sDashletId = $sDashboardDivId."_ID_row".$iRow."_col".$iCol."_".$sDashletOrigId;
|
||||||
if ($bIsCustomized)
|
if ($bIsCustomized) {
|
||||||
{
|
|
||||||
$sDashletId = 'CUSTOM_'.$sDashletId;
|
$sDashletId = 'CUSTOM_'.$sDashletId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -782,9 +748,9 @@ class RuntimeDashboard extends Dashboard
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
protected function SetFormParams($oForm, $aExtraParams = array())
|
protected function SetFormParams($oForm, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
$oForm->SetSubmitParams(utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php', array('operation' => 'update_dashlet_property', 'extra_params' => $aExtraParams));
|
$oForm->SetSubmitParams(utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php', ['operation' => 'update_dashlet_property', 'extra_params' => $aExtraParams]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -800,14 +766,11 @@ class RuntimeDashboard extends Dashboard
|
|||||||
$oUDSearch->AddCondition('menu_code', $this->sId, '=');
|
$oUDSearch->AddCondition('menu_code', $this->sId, '=');
|
||||||
$oUDSet = new DBObjectSet($oUDSearch);
|
$oUDSet = new DBObjectSet($oUDSearch);
|
||||||
$bIsNew = false;
|
$bIsNew = false;
|
||||||
if ($oUDSet->Count() > 0)
|
if ($oUDSet->Count() > 0) {
|
||||||
{
|
|
||||||
// Assuming there is at most one couple {user, menu}!
|
// Assuming there is at most one couple {user, menu}!
|
||||||
$oUserDashboard = $oUDSet->Fetch();
|
$oUserDashboard = $oUDSet->Fetch();
|
||||||
$oUserDashboard->Set('contents', $sXml);
|
$oUserDashboard->Set('contents', $sXml);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// No such customized dashboard for the current user, let's create a new record
|
// No such customized dashboard for the current user, let's create a new record
|
||||||
$oUserDashboard = new UserDashboard();
|
$oUserDashboard = new UserDashboard();
|
||||||
$oUserDashboard->Set('user_id', UserRights::GetUserId());
|
$oUserDashboard->Set('user_id', UserRights::GetUserId());
|
||||||
@@ -838,8 +801,7 @@ class RuntimeDashboard extends Dashboard
|
|||||||
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||||
$oUDSearch->AddCondition('menu_code', $this->sId, '=');
|
$oUDSearch->AddCondition('menu_code', $this->sId, '=');
|
||||||
$oUDSet = new DBObjectSet($oUDSearch);
|
$oUDSet = new DBObjectSet($oUDSearch);
|
||||||
if ($oUDSet->Count() > 0)
|
if ($oUDSet->Count() > 0) {
|
||||||
{
|
|
||||||
// Assuming there is at most one couple {user, menu}!
|
// Assuming there is at most one couple {user, menu}!
|
||||||
$oUserDashboard = $oUDSet->Fetch();
|
$oUserDashboard = $oUDSet->Fetch();
|
||||||
utils::PushArchiveMode(false);
|
utils::PushArchiveMode(false);
|
||||||
@@ -883,14 +845,11 @@ class RuntimeDashboard extends Dashboard
|
|||||||
} else {
|
} else {
|
||||||
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($sDashboardDefinition !== false)
|
if ($sDashboardDefinition !== false) {
|
||||||
{
|
|
||||||
$oDashboard = new RuntimeDashboard($sDashBoardId);
|
$oDashboard = new RuntimeDashboard($sDashBoardId);
|
||||||
$oDashboard->FromXml($sDashboardDefinition);
|
$oDashboard->FromXml($sDashboardDefinition);
|
||||||
$oDashboard->SetCustomFlag($bCustomized);
|
$oDashboard->SetCustomFlag($bCustomized);
|
||||||
@@ -937,7 +896,6 @@ class RuntimeDashboard extends Dashboard
|
|||||||
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($sDashboardDefinition !== false) {
|
if ($sDashboardDefinition !== false) {
|
||||||
$oDashboard = new RuntimeDashboard($sDashBoardId);
|
$oDashboard = new RuntimeDashboard($sDashBoardId);
|
||||||
$oDashboard->FromXml($sDashboardDefinition);
|
$oDashboard->FromXml($sDashboardDefinition);
|
||||||
@@ -954,11 +912,11 @@ class RuntimeDashboard extends Dashboard
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array(), $bCanEdit = true)
|
public function Render($oPage, $bEditMode = false, $aExtraParams = [], $bCanEdit = true)
|
||||||
{
|
{
|
||||||
if (!isset($aExtraParams['query_params']) && isset($aExtraParams['this->class'])) {
|
if (!isset($aExtraParams['query_params']) && isset($aExtraParams['this->class'])) {
|
||||||
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
||||||
$aRenderParams = array('query_params' => $oObj->ToArgsForQuery());
|
$aRenderParams = ['query_params' => $oObj->ToArgsForQuery()];
|
||||||
} else {
|
} else {
|
||||||
$aRenderParams = $aExtraParams;
|
$aRenderParams = $aExtraParams;
|
||||||
}
|
}
|
||||||
@@ -968,7 +926,7 @@ class RuntimeDashboard extends Dashboard
|
|||||||
if (isset($aExtraParams['query_params']['this->object()'])) {
|
if (isset($aExtraParams['query_params']['this->object()'])) {
|
||||||
/** @var \DBObject $oObj */
|
/** @var \DBObject $oObj */
|
||||||
$oObj = $aExtraParams['query_params']['this->object()'];
|
$oObj = $aExtraParams['query_params']['this->object()'];
|
||||||
$aAjaxParams = array('this->class' => get_class($oObj), 'this->id' => $oObj->GetKey());
|
$aAjaxParams = ['this->class' => get_class($oObj), 'this->id' => $oObj->GetKey()];
|
||||||
if (isset($aExtraParams['from_dashboard_page'])) {
|
if (isset($aExtraParams['from_dashboard_page'])) {
|
||||||
$aAjaxParams['from_dashboard_page'] = $aExtraParams['from_dashboard_page'];
|
$aAjaxParams['from_dashboard_page'] = $aExtraParams['from_dashboard_page'];
|
||||||
}
|
}
|
||||||
@@ -1001,9 +959,7 @@ class RuntimeDashboard extends Dashboard
|
|||||||
}
|
}
|
||||||
JS
|
JS
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oPage->add_script(
|
$oPage->add_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
if (typeof(AutoReloadDashboardId$sDivId) !== 'undefined')
|
if (typeof(AutoReloadDashboardId$sDivId) !== 'undefined')
|
||||||
@@ -1032,7 +988,7 @@ EOF
|
|||||||
* @throws \CoreUnexpectedValue
|
* @throws \CoreUnexpectedValue
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
protected function RenderSelector(WebPage $oPage, DashboardLayoutUIBlock $oDashboard, $aAjaxParams = array())
|
protected function RenderSelector(WebPage $oPage, DashboardLayoutUIBlock $oDashboard, $aAjaxParams = [])
|
||||||
{
|
{
|
||||||
if (!$this->HasCustomDashboard()) {
|
if (!$this->HasCustomDashboard()) {
|
||||||
return;
|
return;
|
||||||
@@ -1092,8 +1048,7 @@ JS
|
|||||||
*/
|
*/
|
||||||
protected function HasCustomDashboard()
|
protected function HasCustomDashboard()
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
// Search for an eventual user defined dashboard
|
// Search for an eventual user defined dashboard
|
||||||
$oUDSearch = new DBObjectSearch('UserDashboard');
|
$oUDSearch = new DBObjectSearch('UserDashboard');
|
||||||
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||||
@@ -1101,9 +1056,7 @@ JS
|
|||||||
$oUDSet = new DBObjectSet($oUDSearch);
|
$oUDSet = new DBObjectSet($oUDSearch);
|
||||||
|
|
||||||
return ($oUDSet->Count() > 0);
|
return ($oUDSet->Count() > 0);
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1139,21 +1092,23 @@ JS
|
|||||||
->AddCSSClass('ibo-action-button');
|
->AddCSSClass('ibo-action-button');
|
||||||
|
|
||||||
$oToolbar->AddSubBlock($oActionButton);
|
$oToolbar->AddSubBlock($oActionButton);
|
||||||
$aActions = array();
|
$aActions = [];
|
||||||
$sFile = addslashes(utils::LocalPath($this->sDefinitionFile));
|
$sFile = addslashes(utils::LocalPath($this->sDefinitionFile));
|
||||||
$sJSExtraParams = json_encode($aExtraParams);
|
$sJSExtraParams = json_encode($aExtraParams);
|
||||||
if ($this->HasCustomDashboard()) {
|
if ($this->HasCustomDashboard()) {
|
||||||
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:EditCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:EditCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
||||||
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
||||||
$oRevert = new JSPopupMenuItem('UI:Dashboard:RevertConfirm', Dict::S('UI:Dashboard:DeleteCustom'),
|
$oRevert = new JSPopupMenuItem(
|
||||||
"if (confirm('".addslashes(Dict::S('UI:Dashboard:RevertConfirm'))."')) return RevertDashboard('{$this->sId}', $sJSExtraParams); else return false");
|
'UI:Dashboard:RevertConfirm',
|
||||||
|
Dict::S('UI:Dashboard:DeleteCustom'),
|
||||||
|
"if (confirm('".addslashes(Dict::S('UI:Dashboard:RevertConfirm'))."')) return RevertDashboard('{$this->sId}', $sJSExtraParams); else return false"
|
||||||
|
);
|
||||||
$aActions[$oRevert->GetUID()] = $oRevert->GetMenuItem();
|
$aActions[$oRevert->GetUID()] = $oRevert->GetMenuItem();
|
||||||
} else {
|
} else {
|
||||||
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:CreateCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:CreateCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
||||||
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_DASHBOARD_ACTIONS, $this, $aActions);
|
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_DASHBOARD_ACTIONS, $this, $aActions);
|
||||||
|
|
||||||
$oActionsMenu = $oPage->GetPopoverMenu($sPopoverMenuId, $aActions)
|
$oActionsMenu = $oPage->GetPopoverMenu($sPopoverMenuId, $aActions)
|
||||||
@@ -1193,12 +1148,12 @@ EOF
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function RenderProperties($oPage, $aExtraParams = array())
|
public function RenderProperties($oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
parent::RenderProperties($oPage, $aExtraParams);
|
parent::RenderProperties($oPage, $aExtraParams);
|
||||||
|
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
$('#select_layout input').on('click', function() {
|
$('#select_layout input').on('click', function() {
|
||||||
var sLayoutClass = $(this).val();
|
var sLayoutClass = $(this).val();
|
||||||
$('.itop-dashboard').runtimedashboard('option', {layout_class: sLayoutClass});
|
$('.itop-dashboard').runtimedashboard('option', {layout_class: sLayoutClass});
|
||||||
@@ -1225,7 +1180,6 @@ EOF
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param WebPage $oPage
|
* @param WebPage $oPage
|
||||||
*
|
*
|
||||||
@@ -1236,11 +1190,11 @@ EOF
|
|||||||
* @throws \ReflectionException
|
* @throws \ReflectionException
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function RenderEditor($oPage, $aExtraParams = array())
|
public function RenderEditor($oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
if (isset($aExtraParams['this->class'])) {
|
if (isset($aExtraParams['this->class'])) {
|
||||||
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
||||||
$aRenderParams = array('query_params' => $oObj->ToArgsForQuery());
|
$aRenderParams = ['query_params' => $oObj->ToArgsForQuery()];
|
||||||
} else {
|
} else {
|
||||||
$aRenderParams = $aExtraParams;
|
$aRenderParams = $aExtraParams;
|
||||||
}
|
}
|
||||||
@@ -1262,7 +1216,7 @@ EOF
|
|||||||
$sDialogTitle = Dict::S('UI:DashboardEdit:Title');
|
$sDialogTitle = Dict::S('UI:DashboardEdit:Title');
|
||||||
$sOkButtonLabel = Dict::S('UI:Button:Save');
|
$sOkButtonLabel = Dict::S('UI:Button:Save');
|
||||||
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
||||||
|
|
||||||
$sId = json_encode($this->sId);
|
$sId = json_encode($this->sId);
|
||||||
$sLayoutClass = json_encode($this->sLayoutClass);
|
$sLayoutClass = json_encode($this->sLayoutClass);
|
||||||
$sAutoReload = $this->bAutoReload ? 'true' : 'false';
|
$sAutoReload = $this->bAutoReload ? 'true' : 'false';
|
||||||
@@ -1275,9 +1229,9 @@ EOF
|
|||||||
$sExitConfirmationMessage = addslashes(Dict::S('UI:NavigateAwayConfirmationMessage'));
|
$sExitConfirmationMessage = addslashes(Dict::S('UI:NavigateAwayConfirmationMessage'));
|
||||||
$sCancelConfirmationMessage = addslashes(Dict::S('UI:CancelConfirmationMessage'));
|
$sCancelConfirmationMessage = addslashes(Dict::S('UI:CancelConfirmationMessage'));
|
||||||
$sAutoApplyConfirmationMessage = addslashes(Dict::S('UI:AutoApplyConfirmationMessage'));
|
$sAutoApplyConfirmationMessage = addslashes(Dict::S('UI:AutoApplyConfirmationMessage'));
|
||||||
|
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<JS
|
<<<JS
|
||||||
window.bLeavingOnUserAction = false;
|
window.bLeavingOnUserAction = false;
|
||||||
|
|
||||||
$('#dashboard_editor').dialog({
|
$('#dashboard_editor').dialog({
|
||||||
@@ -1385,104 +1339,89 @@ JS
|
|||||||
$sContextMenuId = $oAppContext->GetCurrentValue('menu', null);
|
$sContextMenuId = $oAppContext->GetCurrentValue('menu', null);
|
||||||
|
|
||||||
$oForm = new DesignerForm();
|
$oForm = new DesignerForm();
|
||||||
|
|
||||||
// Get the list of all 'dashboard' menus in which we can insert a dashlet
|
// Get the list of all 'dashboard' menus in which we can insert a dashlet
|
||||||
$aAllMenus = ApplicationMenu::ReflectionMenuNodes();
|
$aAllMenus = ApplicationMenu::ReflectionMenuNodes();
|
||||||
$sRootMenuId = ApplicationMenu::GetRootMenuId($sContextMenuId);
|
$sRootMenuId = ApplicationMenu::GetRootMenuId($sContextMenuId);
|
||||||
$aAllowedDashboards = array();
|
$aAllowedDashboards = [];
|
||||||
$sDefaultDashboard = null;
|
$sDefaultDashboard = null;
|
||||||
|
|
||||||
// Store the parent menus for acces check
|
// Store the parent menus for acces check
|
||||||
$aParentMenus = array();
|
$aParentMenus = [];
|
||||||
foreach($aAllMenus as $idx => $aMenu)
|
foreach ($aAllMenus as $idx => $aMenu) {
|
||||||
{
|
/** @var MenuNode $oMenu */
|
||||||
/** @var MenuNode $oMenu */
|
|
||||||
$oMenu = $aMenu['node'];
|
|
||||||
if (count(ApplicationMenu::GetChildren($oMenu->GetIndex())) > 0)
|
|
||||||
{
|
|
||||||
$aParentMenus[$oMenu->GetMenuId()] = $aMenu;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($aAllMenus as $idx => $aMenu)
|
|
||||||
{
|
|
||||||
$oMenu = $aMenu['node'];
|
$oMenu = $aMenu['node'];
|
||||||
if ($oMenu instanceof DashboardMenuNode)
|
if (count(ApplicationMenu::GetChildren($oMenu->GetIndex())) > 0) {
|
||||||
{
|
$aParentMenus[$oMenu->GetMenuId()] = $aMenu;
|
||||||
// Get the root parent for access check
|
}
|
||||||
$sParentId = $aMenu['parent'];
|
|
||||||
$aParentMenu = $aParentMenus[$sParentId];
|
|
||||||
while (isset($aParentMenus[$aParentMenu['parent']]))
|
|
||||||
{
|
|
||||||
// grand parent exists
|
|
||||||
$sParentId = $aParentMenu['parent'];
|
|
||||||
$aParentMenu = $aParentMenus[$sParentId];
|
|
||||||
}
|
|
||||||
/** @var \MenuNode $oParentMenu */
|
|
||||||
$oParentMenu = $aParentMenu['node'];
|
|
||||||
if ($oMenu->IsEnabled() && $oParentMenu->IsEnabled())
|
|
||||||
{
|
|
||||||
$sMenuLabel = $oMenu->GetTitle();
|
|
||||||
$sParentLabel = Dict::S('Menu:'.$sParentId);
|
|
||||||
if ($sParentLabel != $sMenuLabel)
|
|
||||||
{
|
|
||||||
$aAllowedDashboards[$oMenu->GetMenuId()] = $sParentLabel.' - '.$sMenuLabel;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$aAllowedDashboards[$oMenu->GetMenuId()] = $sMenuLabel;
|
|
||||||
}
|
|
||||||
if (empty($sDefaultDashboard) && ($sRootMenuId == ApplicationMenu::GetRootMenuId($oMenu->GetMenuId())))
|
|
||||||
{
|
|
||||||
$sDefaultDashboard = $oMenu->GetMenuId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
asort($aAllowedDashboards);
|
|
||||||
|
foreach ($aAllMenus as $idx => $aMenu) {
|
||||||
$oField = new DesignerComboField('menu_id', Dict::S('UI:DashletCreation:Dashboard'), $sDefaultDashboard);
|
$oMenu = $aMenu['node'];
|
||||||
$oField->SetAllowedValues($aAllowedDashboards);
|
if ($oMenu instanceof DashboardMenuNode) {
|
||||||
$oField->SetMandatory(true);
|
// Get the root parent for access check
|
||||||
$oForm->AddField($oField);
|
$sParentId = $aMenu['parent'];
|
||||||
|
$aParentMenu = $aParentMenus[$sParentId];
|
||||||
// Get the list of possible dashlets that support a creation from
|
while (isset($aParentMenus[$aParentMenu['parent']])) {
|
||||||
// an OQL
|
// grand parent exists
|
||||||
$aDashlets = array();
|
$sParentId = $aParentMenu['parent'];
|
||||||
foreach(get_declared_classes() as $sDashletClass)
|
$aParentMenu = $aParentMenus[$sParentId];
|
||||||
{
|
}
|
||||||
if (is_subclass_of($sDashletClass, 'Dashlet'))
|
/** @var \MenuNode $oParentMenu */
|
||||||
{
|
$oParentMenu = $aParentMenu['node'];
|
||||||
$oReflection = new ReflectionClass($sDashletClass);
|
if ($oMenu->IsEnabled() && $oParentMenu->IsEnabled()) {
|
||||||
if (!$oReflection->isAbstract())
|
$sMenuLabel = $oMenu->GetTitle();
|
||||||
{
|
$sParentLabel = Dict::S('Menu:'.$sParentId);
|
||||||
$aCallSpec = array($sDashletClass, 'CanCreateFromOQL');
|
if ($sParentLabel != $sMenuLabel) {
|
||||||
$bShorcutMode = call_user_func($aCallSpec);
|
$aAllowedDashboards[$oMenu->GetMenuId()] = $sParentLabel.' - '.$sMenuLabel;
|
||||||
if ($bShorcutMode)
|
} else {
|
||||||
{
|
$aAllowedDashboards[$oMenu->GetMenuId()] = $sMenuLabel;
|
||||||
$aCallSpec = array($sDashletClass, 'GetInfo');
|
}
|
||||||
$aInfo = call_user_func($aCallSpec);
|
if (empty($sDefaultDashboard) && ($sRootMenuId == ApplicationMenu::GetRootMenuId($oMenu->GetMenuId()))) {
|
||||||
$aDashlets[$sDashletClass] = array('label' => $aInfo['label'], 'class' => $sDashletClass, 'icon' => $aInfo['icon']);
|
$sDefaultDashboard = $oMenu->GetMenuId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
asort($aAllowedDashboards);
|
||||||
|
|
||||||
|
$oField = new DesignerComboField('menu_id', Dict::S('UI:DashletCreation:Dashboard'), $sDefaultDashboard);
|
||||||
|
$oField->SetAllowedValues($aAllowedDashboards);
|
||||||
|
$oField->SetMandatory(true);
|
||||||
|
$oForm->AddField($oField);
|
||||||
|
|
||||||
|
// Get the list of possible dashlets that support a creation from
|
||||||
|
// an OQL
|
||||||
|
$aDashlets = [];
|
||||||
|
foreach (get_declared_classes() as $sDashletClass) {
|
||||||
|
if (is_subclass_of($sDashletClass, 'Dashlet')) {
|
||||||
|
$oReflection = new ReflectionClass($sDashletClass);
|
||||||
|
if (!$oReflection->isAbstract()) {
|
||||||
|
$aCallSpec = [$sDashletClass, 'CanCreateFromOQL'];
|
||||||
|
$bShorcutMode = call_user_func($aCallSpec);
|
||||||
|
if ($bShorcutMode) {
|
||||||
|
$aCallSpec = [$sDashletClass, 'GetInfo'];
|
||||||
|
$aInfo = call_user_func($aCallSpec);
|
||||||
|
$aDashlets[$sDashletClass] = ['label' => $aInfo['label'], 'class' => $sDashletClass, 'icon' => $aInfo['icon']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$oSelectorField = new DesignerFormSelectorField('dashlet_class', Dict::S('UI:DashletCreation:DashletType'), '');
|
$oSelectorField = new DesignerFormSelectorField('dashlet_class', Dict::S('UI:DashletCreation:DashletType'), '');
|
||||||
$oForm->AddField($oSelectorField);
|
$oForm->AddField($oSelectorField);
|
||||||
foreach($aDashlets as $sDashletClass => $aDashletInfo)
|
foreach ($aDashlets as $sDashletClass => $aDashletInfo) {
|
||||||
{
|
|
||||||
$oSubForm = new DesignerForm();
|
$oSubForm = new DesignerForm();
|
||||||
$oMetaModel = new ModelReflectionRuntime();
|
$oMetaModel = new ModelReflectionRuntime();
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
$oDashlet = new $sDashletClass($oMetaModel, 0);
|
$oDashlet = new $sDashletClass($oMetaModel, 0);
|
||||||
$oDashlet->GetPropertiesFieldsFromOQL($oSubForm, $sOQL);
|
$oDashlet->GetPropertiesFieldsFromOQL($oSubForm, $sOQL);
|
||||||
|
|
||||||
$oSelectorField->AddSubForm($oSubForm, $aDashletInfo['label'], $aDashletInfo['class']);
|
$oSelectorField->AddSubForm($oSubForm, $aDashletInfo['label'], $aDashletInfo['class']);
|
||||||
}
|
}
|
||||||
$oField = new DesignerBooleanField('open_editor', Dict::S('UI:DashletCreation:EditNow'), true);
|
$oField = new DesignerBooleanField('open_editor', Dict::S('UI:DashletCreation:EditNow'), true);
|
||||||
$oForm->AddField($oField);
|
$oForm->AddField($oField);
|
||||||
|
|
||||||
return $oForm;
|
return $oForm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1501,11 +1440,11 @@ JS
|
|||||||
|
|
||||||
$oForm->Render($oPage);
|
$oForm->Render($oPage);
|
||||||
$oPage->add('</div>');
|
$oPage->add('</div>');
|
||||||
|
|
||||||
$sDialogTitle = Dict::S('UI:DashletCreation:Title');
|
$sDialogTitle = Dict::S('UI:DashletCreation:Title');
|
||||||
$sOkButtonLabel = Dict::S('UI:Button:Ok');
|
$sOkButtonLabel = Dict::S('UI:Button:Ok');
|
||||||
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
||||||
|
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<JS
|
<<<JS
|
||||||
$('#dashlet_creation_dlg').dialog({
|
$('#dashlet_creation_dlg').dialog({
|
||||||
@@ -1603,7 +1542,7 @@ JS
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = array())
|
protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
$sDashletIdOrig = $oDashlet->GetID();
|
$sDashletIdOrig = $oDashlet->GetID();
|
||||||
$sDashboardSanitizedId = $this->GetSanitizedId();
|
$sDashboardSanitizedId = $this->GetSanitizedId();
|
||||||
@@ -1630,31 +1569,27 @@ JS
|
|||||||
private function UpdateDashletUserPrefs(Dashlet $oDashlet, $sDashletIdOrig, array $aExtraParams)
|
private function UpdateDashletUserPrefs(Dashlet $oDashlet, $sDashletIdOrig, array $aExtraParams)
|
||||||
{
|
{
|
||||||
$bIsDashletWithListPref = ($oDashlet instanceof DashletObjectList);
|
$bIsDashletWithListPref = ($oDashlet instanceof DashletObjectList);
|
||||||
if (!$bIsDashletWithListPref)
|
if (!$bIsDashletWithListPref) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/** @var \DashletObjectList $oDashlet */
|
/** @var \DashletObjectList $oDashlet */
|
||||||
|
|
||||||
$bDashletIdInNewFormat = ($sDashletIdOrig === $oDashlet->GetID());
|
$bDashletIdInNewFormat = ($sDashletIdOrig === $oDashlet->GetID());
|
||||||
if ($bDashletIdInNewFormat)
|
if ($bDashletIdInNewFormat) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sNewPrefKey = $this->GetDashletObjectListAppUserPreferencesPrefix($oDashlet, $aExtraParams, $oDashlet->GetID());
|
$sNewPrefKey = $this->GetDashletObjectListAppUserPreferencesPrefix($oDashlet, $aExtraParams, $oDashlet->GetID());
|
||||||
$sPrefValueForNewKey = appUserPreferences::GetPref($sNewPrefKey, null);
|
$sPrefValueForNewKey = appUserPreferences::GetPref($sNewPrefKey, null);
|
||||||
$bHasPrefInNewFormat = ($sPrefValueForNewKey !== null);
|
$bHasPrefInNewFormat = ($sPrefValueForNewKey !== null);
|
||||||
if ($bHasPrefInNewFormat)
|
if ($bHasPrefInNewFormat) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sOldPrefKey = $this->GetDashletObjectListAppUserPreferencesPrefix($oDashlet, $aExtraParams, $sDashletIdOrig);
|
$sOldPrefKey = $this->GetDashletObjectListAppUserPreferencesPrefix($oDashlet, $aExtraParams, $sDashletIdOrig);
|
||||||
$sPrefValueForOldKey = appUserPreferences::GetPref($sOldPrefKey, null);
|
$sPrefValueForOldKey = appUserPreferences::GetPref($sOldPrefKey, null);
|
||||||
$bHasPrefInOldFormat = ($sPrefValueForOldKey !== null);
|
$bHasPrefInOldFormat = ($sPrefValueForOldKey !== null);
|
||||||
if (!$bHasPrefInOldFormat)
|
if (!$bHasPrefInOldFormat) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1673,7 +1608,7 @@ JS
|
|||||||
private function GetDashletObjectListAppUserPreferencesPrefix(DashletObjectList $oDashlet, $aExtraParams, $sDashletId)
|
private function GetDashletObjectListAppUserPreferencesPrefix(DashletObjectList $oDashlet, $aExtraParams, $sDashletId)
|
||||||
{
|
{
|
||||||
$sDataTableId = Dashlet::APPUSERPREFERENCES_PREFIX.$sDashletId;
|
$sDataTableId = Dashlet::APPUSERPREFERENCES_PREFIX.$sDashletId;
|
||||||
$aClassAliases = array();
|
$aClassAliases = [];
|
||||||
try {
|
try {
|
||||||
$oFilter = $oDashlet->GetDBSearch($aExtraParams);
|
$oFilter = $oDashlet->GetDBSearch($aExtraParams);
|
||||||
$aClassAliases = $oFilter->GetSelectedClasses();
|
$aClassAliases = $oFilter->GetSelectedClasses();
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// 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
|
// 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
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -38,21 +39,21 @@ abstract class DashboardLayout
|
|||||||
* @since 2.7.0
|
* @since 2.7.0
|
||||||
*/
|
*/
|
||||||
abstract public function GetDashletCoordinates($iCellIdx);
|
abstract public function GetDashletCoordinates($iCellIdx);
|
||||||
|
|
||||||
public static function GetInfo()
|
public static function GetInfo()
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
'label' => '',
|
'label' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'description' => '',
|
'description' => '',
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class DashboardLayoutMultiCol extends DashboardLayout
|
abstract class DashboardLayoutMultiCol extends DashboardLayout
|
||||||
{
|
{
|
||||||
protected $iNbCols;
|
protected $iNbCols;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->iNbCols = 1;
|
$this->iNbCols = 1;
|
||||||
@@ -63,47 +64,38 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
|||||||
$aKeys = array_reverse(array_keys($aDashlets));
|
$aKeys = array_reverse(array_keys($aDashlets));
|
||||||
$idx = 0;
|
$idx = 0;
|
||||||
$bNoVisibleFound = true;
|
$bNoVisibleFound = true;
|
||||||
while($idx < count($aKeys) && $bNoVisibleFound)
|
while ($idx < count($aKeys) && $bNoVisibleFound) {
|
||||||
{
|
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
$oDashlet = $aDashlets[$aKeys[$idx]];
|
$oDashlet = $aDashlets[$aKeys[$idx]];
|
||||||
if ($oDashlet::IsVisible())
|
if ($oDashlet::IsVisible()) {
|
||||||
{
|
|
||||||
$bNoVisibleFound = false;
|
$bNoVisibleFound = false;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
unset($aDashlets[$aKeys[$idx]]);
|
unset($aDashlets[$aKeys[$idx]]);
|
||||||
}
|
}
|
||||||
$idx++;
|
$idx++;
|
||||||
}
|
}
|
||||||
return $aDashlets;
|
return $aDashlets;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function TrimCellsArray($aCells)
|
protected function TrimCellsArray($aCells)
|
||||||
{
|
{
|
||||||
foreach($aCells as $key => $aDashlets)
|
foreach ($aCells as $key => $aDashlets) {
|
||||||
{
|
|
||||||
$aCells[$key] = $this->TrimCell($aDashlets);
|
$aCells[$key] = $this->TrimCell($aDashlets);
|
||||||
}
|
}
|
||||||
$aKeys = array_reverse(array_keys($aCells));
|
$aKeys = array_reverse(array_keys($aCells));
|
||||||
$idx = 0;
|
$idx = 0;
|
||||||
$bNoVisibleFound = true;
|
$bNoVisibleFound = true;
|
||||||
while($idx < count($aKeys) && $bNoVisibleFound)
|
while ($idx < count($aKeys) && $bNoVisibleFound) {
|
||||||
{
|
|
||||||
$aDashlets = $aCells[$aKeys[$idx]];
|
$aDashlets = $aCells[$aKeys[$idx]];
|
||||||
if (count($aDashlets) > 0)
|
if (count($aDashlets) > 0) {
|
||||||
{
|
|
||||||
$bNoVisibleFound = false;
|
$bNoVisibleFound = false;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
unset($aCells[$aKeys[$idx]]);
|
unset($aCells[$aKeys[$idx]]);
|
||||||
}
|
}
|
||||||
$idx++;
|
$idx++;
|
||||||
}
|
}
|
||||||
return $aCells;
|
return $aCells;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,7 +104,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
|||||||
* @param bool $bEditMode
|
* @param bool $bEditMode
|
||||||
* @param array $aExtraParams
|
* @param array $aExtraParams
|
||||||
*/
|
*/
|
||||||
public function Render($oPage, $aCells, $bEditMode = false, $aExtraParams = array())
|
public function Render($oPage, $aCells, $bEditMode = false, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
// Trim the list of cells to remove the invisible/empty ones at the end of the array
|
// Trim the list of cells to remove the invisible/empty ones at the end of the array
|
||||||
$aCells = $this->TrimCellsArray($aCells);
|
$aCells = $this->TrimCellsArray($aCells);
|
||||||
@@ -157,8 +149,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
|||||||
|
|
||||||
$oPage->add_script("function updateDashboard".$aExtraParams['dashboard_div_id']."(){".$sJSReload."}");
|
$oPage->add_script("function updateDashboard".$aExtraParams['dashboard_div_id']."(){".$sJSReload."}");
|
||||||
|
|
||||||
if ($bEditMode) // Add one row for extensibility
|
if ($bEditMode) { // Add one row for extensibility
|
||||||
{
|
|
||||||
$oDashboardRow = new DashboardRow();
|
$oDashboardRow = new DashboardRow();
|
||||||
$oDashboardLayout->AddDashboardRow($oDashboardRow);
|
$oDashboardLayout->AddDashboardRow($oDashboardRow);
|
||||||
|
|
||||||
@@ -180,7 +171,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
|||||||
$iColNumber = (int) $iCellIdx % $this->iNbCols;
|
$iColNumber = (int) $iCellIdx % $this->iNbCols;
|
||||||
$iRowNumber = (int) floor($iCellIdx / $this->iNbCols);
|
$iRowNumber = (int) floor($iCellIdx / $this->iNbCols);
|
||||||
|
|
||||||
return array($iColNumber, $iRowNumber);
|
return [$iColNumber, $iRowNumber];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,13 +182,13 @@ class DashboardLayoutOneCol extends DashboardLayoutMultiCol
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->iNbCols = 1;
|
$this->iNbCols = 1;
|
||||||
}
|
}
|
||||||
static public function GetInfo()
|
public static function GetInfo()
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
'label' => 'One Column',
|
'label' => 'One Column',
|
||||||
'icon' => 'images/layout_1col.png',
|
'icon' => 'images/layout_1col.png',
|
||||||
'description' => '',
|
'description' => '',
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,13 +199,13 @@ class DashboardLayoutTwoCols extends DashboardLayoutMultiCol
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->iNbCols = 2;
|
$this->iNbCols = 2;
|
||||||
}
|
}
|
||||||
static public function GetInfo()
|
public static function GetInfo()
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
'label' => 'Two Columns',
|
'label' => 'Two Columns',
|
||||||
'icon' => 'images/layout_2col.png',
|
'icon' => 'images/layout_2col.png',
|
||||||
'description' => '',
|
'description' => '',
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,12 +216,12 @@ class DashboardLayoutThreeCols extends DashboardLayoutMultiCol
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->iNbCols = 3;
|
$this->iNbCols = 3;
|
||||||
}
|
}
|
||||||
static public function GetInfo()
|
public static function GetInfo()
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
'label' => 'Two Columns',
|
'label' => 'Two Columns',
|
||||||
'icon' => 'images/layout_3col.png',
|
'icon' => 'images/layout_3col.png',
|
||||||
'description' => '',
|
'description' => '',
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -80,42 +80,31 @@ class DataTable
|
|||||||
|
|
||||||
// Identified tables can have their own specific settings
|
// Identified tables can have their own specific settings
|
||||||
$oCustomSettings = DataTableSettings::GetTableSettings($this->aClassAliases, $this->sTableId);
|
$oCustomSettings = DataTableSettings::GetTableSettings($this->aClassAliases, $this->sTableId);
|
||||||
|
|
||||||
if ($oCustomSettings != null)
|
if ($oCustomSettings != null) {
|
||||||
{
|
|
||||||
// Custom settings overload the default ones
|
// Custom settings overload the default ones
|
||||||
$this->bUseCustomSettings = true;
|
$this->bUseCustomSettings = true;
|
||||||
if ($this->oDefaultSettings->iDefaultPageSize == 0)
|
if ($this->oDefaultSettings->iDefaultPageSize == 0) {
|
||||||
{
|
|
||||||
$oCustomSettings->iDefaultPageSize = 0;
|
$oCustomSettings->iDefaultPageSize = 0;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oCustomSettings = $oSettings;
|
$oCustomSettings = $oSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($oCustomSettings->iDefaultPageSize > 0)
|
if ($oCustomSettings->iDefaultPageSize > 0) {
|
||||||
{
|
|
||||||
$this->oSet->SetLimit($oCustomSettings->iDefaultPageSize);
|
$this->oSet->SetLimit($oCustomSettings->iDefaultPageSize);
|
||||||
}
|
}
|
||||||
$this->oSet->SetOrderBy($oCustomSettings->GetSortOrder());
|
$this->oSet->SetOrderBy($oCustomSettings->GetSortOrder());
|
||||||
|
|
||||||
// Load only the requested columns
|
// Load only the requested columns
|
||||||
$aColumnsToLoad = array();
|
$aColumnsToLoad = [];
|
||||||
foreach($oCustomSettings->aColumns as $sAlias => $aColumnsInfo)
|
foreach ($oCustomSettings->aColumns as $sAlias => $aColumnsInfo) {
|
||||||
{
|
foreach ($aColumnsInfo as $sAttCode => $aData) {
|
||||||
foreach($aColumnsInfo as $sAttCode => $aData)
|
if ($sAttCode != '_key_') {
|
||||||
{
|
if ($aData['checked']) {
|
||||||
if ($sAttCode != '_key_')
|
|
||||||
{
|
|
||||||
if ($aData['checked'])
|
|
||||||
{
|
|
||||||
$aColumnsToLoad[$sAlias][] = $sAttCode;
|
$aColumnsToLoad[$sAlias][] = $sAttCode;
|
||||||
}
|
} else {
|
||||||
else
|
// See if this column is a must to load
|
||||||
{
|
|
||||||
// See if this column is a must to load
|
|
||||||
$sClass = $this->aClassAliases[$sAlias];
|
$sClass = $this->aClassAliases[$sAlias];
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
if ($oAttDef->AlwaysLoadInTables()) {
|
if ($oAttDef->AlwaysLoadInTables()) {
|
||||||
@@ -127,18 +116,15 @@ class DataTable
|
|||||||
}
|
}
|
||||||
$this->oSet->OptimizeColumnLoad($aColumnsToLoad);
|
$this->oSet->OptimizeColumnLoad($aColumnsToLoad);
|
||||||
|
|
||||||
|
|
||||||
$bToolkitMenu = true;
|
$bToolkitMenu = true;
|
||||||
if (isset($aExtraParams['toolkit_menu']))
|
if (isset($aExtraParams['toolkit_menu'])) {
|
||||||
{
|
|
||||||
$bToolkitMenu = (bool) $aExtraParams['toolkit_menu'];
|
$bToolkitMenu = (bool) $aExtraParams['toolkit_menu'];
|
||||||
}
|
}
|
||||||
if (UserRights::IsPortalUser())
|
if (UserRights::IsPortalUser()) {
|
||||||
{
|
|
||||||
// Portal users have a limited access to data, for now they can only see what's configured for them
|
// Portal users have a limited access to data, for now they can only see what's configured for them
|
||||||
$bToolkitMenu = false;
|
$bToolkitMenu = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->GetAsHTML($oPage, $oCustomSettings->iDefaultPageSize, $oCustomSettings->iDefaultPageSize, 0, $oCustomSettings->aColumns, $bActionsMenu, $bToolkitMenu, $sSelectMode, $bViewLink, $aExtraParams);
|
return $this->GetAsHTML($oPage, $oCustomSettings->iDefaultPageSize, $oCustomSettings->iDefaultPageSize, 0, $oCustomSettings->aColumns, $bActionsMenu, $bToolkitMenu, $sSelectMode, $bViewLink, $aExtraParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,10 +153,10 @@ class DataTable
|
|||||||
if ($bActionsMenu) {
|
if ($bActionsMenu) {
|
||||||
$sActionsMenu = $this->GetActionsMenu($oPage, $aExtraParams);
|
$sActionsMenu = $this->GetActionsMenu($oPage, $aExtraParams);
|
||||||
}
|
}
|
||||||
// if ($bToolkitMenu)
|
// if ($bToolkitMenu)
|
||||||
// {
|
// {
|
||||||
// $sToolkitMenu = $this->GetToolkitMenu($oPage, $aExtraParams);
|
// $sToolkitMenu = $this->GetToolkitMenu($oPage, $aExtraParams);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
$sDataTable = $this->GetHTMLTable($oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
$sDataTable = $this->GetHTMLTable($oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
||||||
$sConfigDlg = $this->GetTableConfigDlg($oPage, $aColumns, $bViewLink, $iDefaultPageSize);
|
$sConfigDlg = $this->GetTableConfigDlg($oPage, $aColumns, $bViewLink, $iDefaultPageSize);
|
||||||
@@ -188,7 +174,7 @@ class DataTable
|
|||||||
|
|
||||||
$aExtraParams['show_obsolete_data'] = $this->bShowObsoleteData;
|
$aExtraParams['show_obsolete_data'] = $this->bShowObsoleteData;
|
||||||
|
|
||||||
$aOptions = array(
|
$aOptions = [
|
||||||
'sPersistentId' => '',
|
'sPersistentId' => '',
|
||||||
'sFilter' => $this->oSet->GetFilter()->serialize(),
|
'sFilter' => $this->oSet->GetFilter()->serialize(),
|
||||||
'oColumns' => $aColumns,
|
'oColumns' => $aColumns,
|
||||||
@@ -202,12 +188,11 @@ class DataTable
|
|||||||
'sTableId' => $this->sTableId,
|
'sTableId' => $this->sTableId,
|
||||||
'oExtraParams' => $aExtraParams,
|
'oExtraParams' => $aExtraParams,
|
||||||
'sRenderUrl' => utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php',
|
'sRenderUrl' => utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php',
|
||||||
'oRenderParameters' => array('str' => ''), // Forces JSON to encode this as a object...
|
'oRenderParameters' => ['str' => ''], // Forces JSON to encode this as a object...
|
||||||
'oDefaultSettings' => array('str' => ''), // Forces JSON to encode this as a object...
|
'oDefaultSettings' => ['str' => ''], // Forces JSON to encode this as a object...
|
||||||
'oLabels' => array('moveup' => Dict::S('UI:Button:MoveUp'), 'movedown' => Dict::S('UI:Button:MoveDown')),
|
'oLabels' => ['moveup' => Dict::S('UI:Button:MoveUp'), 'movedown' => Dict::S('UI:Button:MoveDown')],
|
||||||
);
|
];
|
||||||
if($this->oDefaultSettings != null)
|
if ($this->oDefaultSettings != null) {
|
||||||
{
|
|
||||||
$aOptions['oDefaultSettings'] = $this->GetAsHash($this->oDefaultSettings);
|
$aOptions['oDefaultSettings'] = $this->GetAsHash($this->oDefaultSettings);
|
||||||
}
|
}
|
||||||
$sJSOptions = json_encode($aOptions);
|
$sJSOptions = json_encode($aOptions);
|
||||||
@@ -222,16 +207,14 @@ class DataTable
|
|||||||
*/
|
*/
|
||||||
public function GetAsHTMLTableRows(WebPage $oPage, $iPageSize, $aColumns, $sSelectMode, $bViewLink, $aExtraParams)
|
public function GetAsHTMLTableRows(WebPage $oPage, $iPageSize, $aColumns, $sSelectMode, $bViewLink, $aExtraParams)
|
||||||
{
|
{
|
||||||
if ($iPageSize < 1)
|
if ($iPageSize < 1) {
|
||||||
{
|
|
||||||
$iPageSize = -1; // convention: no pagination
|
$iPageSize = -1; // convention: no pagination
|
||||||
}
|
}
|
||||||
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
||||||
$aValues = $this->GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
$aValues = $this->GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
||||||
|
|
||||||
$sHtml = '';
|
$sHtml = '';
|
||||||
foreach($aValues as $aRow)
|
foreach ($aValues as $aRow) {
|
||||||
{
|
|
||||||
$sHtml .= $oPage->GetTableRow($aRow, $aAttribs);
|
$sHtml .= $oPage->GetTableRow($aRow, $aAttribs);
|
||||||
}
|
}
|
||||||
return $sHtml;
|
return $sHtml;
|
||||||
@@ -245,15 +228,12 @@ class DataTable
|
|||||||
*/
|
*/
|
||||||
protected function GetObjectCount(WebPage $oPage, $sSelectMode)
|
protected function GetObjectCount(WebPage $oPage, $sSelectMode)
|
||||||
{
|
{
|
||||||
if (($sSelectMode == 'single') || ($sSelectMode == 'multiple'))
|
if (($sSelectMode == 'single') || ($sSelectMode == 'multiple')) {
|
||||||
{
|
|
||||||
$sHtml = '<div class="pagination_objcount">'.Dict::Format('UI:Pagination:HeaderSelection', '<span id="total">'.$this->iNbObjects.'</span>', '<span class="selectedCount">0</span>').'</div>';
|
$sHtml = '<div class="pagination_objcount">'.Dict::Format('UI:Pagination:HeaderSelection', '<span id="total">'.$this->iNbObjects.'</span>', '<span class="selectedCount">0</span>').'</div>';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sHtml = '<div class="pagination_objcount">'.Dict::Format('UI:Pagination:HeaderNoSelection', '<span id="total">'.$this->iNbObjects.'</span>').'</div>';
|
$sHtml = '<div class="pagination_objcount">'.Dict::Format('UI:Pagination:HeaderNoSelection', '<span id="total">'.$this->iNbObjects.'</span>').'</div>';
|
||||||
}
|
}
|
||||||
return $sHtml;
|
return $sHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -267,26 +247,19 @@ class DataTable
|
|||||||
protected function GetPager(WebPage $oPage, $iPageSize, $iDefaultPageSize, $iPageIndex)
|
protected function GetPager(WebPage $oPage, $iPageSize, $iDefaultPageSize, $iPageIndex)
|
||||||
{
|
{
|
||||||
$sHtml = '';
|
$sHtml = '';
|
||||||
if ($iPageSize < 1) // Display all
|
if ($iPageSize < 1) { // Display all
|
||||||
{
|
|
||||||
$sPagerStyle = 'style="display:none"'; // no limit: display the full table, so hide the "pager" UI
|
$sPagerStyle = 'style="display:none"'; // no limit: display the full table, so hide the "pager" UI
|
||||||
// WARNING: mPDF does not take the "display" style into account
|
// WARNING: mPDF does not take the "display" style into account
|
||||||
// when applied to a <td> or a <table> tag, so make sure you apply this to a div
|
// when applied to a <td> or a <table> tag, so make sure you apply this to a div
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sPagerStyle = '';
|
$sPagerStyle = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$sCombo = '<select class="pagesize">';
|
$sCombo = '<select class="pagesize">';
|
||||||
if($iPageSize < 1)
|
if ($iPageSize < 1) {
|
||||||
{
|
|
||||||
$sCombo .= "<option selected=\"selected\" value=\"-1\">".Dict::S('UI:Pagination:All')."</option>";
|
$sCombo .= "<option selected=\"selected\" value=\"-1\">".Dict::S('UI:Pagination:All')."</option>";
|
||||||
}
|
} else {
|
||||||
else
|
for ($iPage = 1; $iPage < 5; $iPage++) {
|
||||||
{
|
|
||||||
for($iPage = 1; $iPage < 5; $iPage++)
|
|
||||||
{
|
|
||||||
$iNbItems = $iPage * $iDefaultPageSize;
|
$iNbItems = $iPage * $iDefaultPageSize;
|
||||||
$sSelected = ($iNbItems == $iPageSize) ? 'selected="selected"' : '';
|
$sSelected = ($iNbItems == $iPageSize) ? 'selected="selected"' : '';
|
||||||
$sCombo .= "<option $sSelected value=\"$iNbItems\">$iNbItems</option>";
|
$sCombo .= "<option $sSelected value=\"$iNbItems\">$iNbItems</option>";
|
||||||
@@ -295,31 +268,25 @@ class DataTable
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sCombo .= '</select>';
|
$sCombo .= '</select>';
|
||||||
|
|
||||||
$sPages = Dict::S('UI:Pagination:PagesLabel');
|
$sPages = Dict::S('UI:Pagination:PagesLabel');
|
||||||
$sPageSizeCombo = Dict::Format('UI:Pagination:PageSize', $sCombo);
|
$sPageSizeCombo = Dict::Format('UI:Pagination:PageSize', $sCombo);
|
||||||
|
|
||||||
$iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize);
|
$iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize);
|
||||||
if ($iNbPages == 1)
|
if ($iNbPages == 1) {
|
||||||
{
|
|
||||||
// No need to display the pager
|
// No need to display the pager
|
||||||
$sPagerStyle = 'style="display:none"';
|
$sPagerStyle = 'style="display:none"';
|
||||||
}
|
}
|
||||||
$aPagesToDisplay = array();
|
$aPagesToDisplay = [];
|
||||||
for($idx = 0; $idx <= min(4, $iNbPages-1); $idx++)
|
for ($idx = 0; $idx <= min(4, $iNbPages - 1); $idx++) {
|
||||||
{
|
if ($idx == 0) {
|
||||||
if ($idx == 0)
|
|
||||||
{
|
|
||||||
$aPagesToDisplay[$idx] = '<span page="0" class="curr_page">1</span>';
|
$aPagesToDisplay[$idx] = '<span page="0" class="curr_page">1</span>';
|
||||||
}
|
} else {
|
||||||
else
|
$aPagesToDisplay[$idx] = "<span id=\"gotopage_$idx\" class=\"gotopage\" page=\"$idx\">".(1 + $idx)."</span>";
|
||||||
{
|
|
||||||
$aPagesToDisplay[$idx] = "<span id=\"gotopage_$idx\" class=\"gotopage\" page=\"$idx\">".(1+$idx)."</span>";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$iLastPageIdx = $iNbPages - 1;
|
$iLastPageIdx = $iNbPages - 1;
|
||||||
if (!isset($aPagesToDisplay[$iLastPageIdx]))
|
if (!isset($aPagesToDisplay[$iLastPageIdx])) {
|
||||||
{
|
|
||||||
unset($aPagesToDisplay[$idx - 1]); // remove the last page added to make room for the very last page
|
unset($aPagesToDisplay[$idx - 1]); // remove the last page added to make room for the very last page
|
||||||
$aPagesToDisplay[$iLastPageIdx] = "<span id=\"gotopage_$iLastPageIdx\" class=\"gotopage\" page=\"$iLastPageIdx\">... $iNbPages</span>";
|
$aPagesToDisplay[$iLastPageIdx] = "<span id=\"gotopage_$iLastPageIdx\" class=\"gotopage\" page=\"$iLastPageIdx\">... $iNbPages</span>";
|
||||||
}
|
}
|
||||||
@@ -386,22 +353,19 @@ EOF;
|
|||||||
*/
|
*/
|
||||||
protected function GetToolkitMenu(WebPage $oPage, $aExtraParams)
|
protected function GetToolkitMenu(WebPage $oPage, $aExtraParams)
|
||||||
{
|
{
|
||||||
if (!$oPage->IsPrintableVersion())
|
if (!$oPage->IsPrintableVersion()) {
|
||||||
{
|
|
||||||
$sMenuTitle = Dict::S('UI:ConfigureThisList');
|
$sMenuTitle = Dict::S('UI:ConfigureThisList');
|
||||||
$sHtml = '<div class="itop_popup toolkit_menu" id="tk_'.$this->iListId.'"><ul><li aria-label="'.Dict::S('UI:Menu:Toolkit').'"><i class="fas fa-tools"></i><i class="fas fa-caret-down"></i><ul>';
|
$sHtml = '<div class="itop_popup toolkit_menu" id="tk_'.$this->iListId.'"><ul><li aria-label="'.Dict::S('UI:Menu:Toolkit').'"><i class="fas fa-tools"></i><i class="fas fa-caret-down"></i><ul>';
|
||||||
|
|
||||||
$oMenuItem1 = new JSPopupMenuItem('iTop::ConfigureList', $sMenuTitle, "$('#datatable_dlg_".$this->iListId."').dialog('open');");
|
$oMenuItem1 = new JSPopupMenuItem('iTop::ConfigureList', $sMenuTitle, "$('#datatable_dlg_".$this->iListId."').dialog('open');");
|
||||||
$aActions = array(
|
$aActions = [
|
||||||
$oMenuItem1->GetUID() => $oMenuItem1->GetMenuItem(),
|
$oMenuItem1->GetUID() => $oMenuItem1->GetMenuItem(),
|
||||||
);
|
];
|
||||||
$this->oSet->Rewind();
|
$this->oSet->Rewind();
|
||||||
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_OBJLIST_TOOLKIT, $this->oSet, $aActions, $this->sTableId, $this->iListId);
|
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_OBJLIST_TOOLKIT, $this->oSet, $aActions, $this->sTableId, $this->iListId);
|
||||||
$this->oSet->Rewind();
|
$this->oSet->Rewind();
|
||||||
$sHtml .= $oPage->RenderPopupMenuItems($aActions);
|
$sHtml .= $oPage->RenderPopupMenuItems($aActions);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sHtml = '';
|
$sHtml = '';
|
||||||
}
|
}
|
||||||
return $sHtml;
|
return $sHtml;
|
||||||
@@ -422,10 +386,10 @@ EOF;
|
|||||||
$sChecked = ($this->bUseCustomSettings) ? '' : 'checked';
|
$sChecked = ($this->bUseCustomSettings) ? '' : 'checked';
|
||||||
$sHtml .= "<p><input id=\"dtbl_dlg_settings_{$this->iListId}\" type=\"radio\" name=\"settings\" $sChecked value=\"defaults\"><label for=\"dtbl_dlg_settings_{$this->iListId}\"> ".Dict::S('UI:UseDefaultSettings').'</label></p>';
|
$sHtml .= "<p><input id=\"dtbl_dlg_settings_{$this->iListId}\" type=\"radio\" name=\"settings\" $sChecked value=\"defaults\"><label for=\"dtbl_dlg_settings_{$this->iListId}\"> ".Dict::S('UI:UseDefaultSettings').'</label></p>';
|
||||||
$sHtml .= "<fieldset>";
|
$sHtml .= "<fieldset>";
|
||||||
$sChecked = ($this->bUseCustomSettings) ? 'checked': '';
|
$sChecked = ($this->bUseCustomSettings) ? 'checked' : '';
|
||||||
$sHtml .= "<legend class=\"transparent\"><input id=\"dtbl_dlg_specific_{$this->iListId}\" type=\"radio\" class=\"specific_settings\" name=\"settings\" $sChecked value=\"specific\"><label for=\"dtbl_dlg_specific_{$this->iListId}\"> ".Dict::S('UI:UseSpecificSettings')."</label></legend>";
|
$sHtml .= "<legend class=\"transparent\"><input id=\"dtbl_dlg_specific_{$this->iListId}\" type=\"radio\" class=\"specific_settings\" name=\"settings\" $sChecked value=\"specific\"><label for=\"dtbl_dlg_specific_{$this->iListId}\"> ".Dict::S('UI:UseSpecificSettings')."</label></legend>";
|
||||||
$sHtml .= Dict::S('UI:ColumnsAndSortOrder').'<br/><ul class="sortable_field_list" id="sfl_'.$this->iListId.'"></ul>';
|
$sHtml .= Dict::S('UI:ColumnsAndSortOrder').'<br/><ul class="sortable_field_list" id="sfl_'.$this->iListId.'"></ul>';
|
||||||
|
|
||||||
$sHtml .= '<p>'.Dict::Format('UI:Display_X_ItemsPerPage', '<input type="text" size="4" name="page_size" value="'.$iDefaultPageSize.'">').'</p>';
|
$sHtml .= '<p>'.Dict::Format('UI:Display_X_ItemsPerPage', '<input type="text" size="4" name="page_size" value="'.$iDefaultPageSize.'">').'</p>';
|
||||||
$sHtml .= "</fieldset>";
|
$sHtml .= "</fieldset>";
|
||||||
$sHtml .= "<fieldset>";
|
$sHtml .= "<fieldset>";
|
||||||
@@ -444,7 +408,7 @@ EOF;
|
|||||||
$sHtml .= '</td></tr></table>';
|
$sHtml .= '</td></tr></table>';
|
||||||
$sHtml .= "</form>";
|
$sHtml .= "</form>";
|
||||||
$sHtml .= "</div>";
|
$sHtml .= "</div>";
|
||||||
|
|
||||||
$sDlgTitle = addslashes(Dict::S('UI:ListConfigurationTitle'));
|
$sDlgTitle = addslashes(Dict::S('UI:ListConfigurationTitle'));
|
||||||
$oPage->add_ready_script("$('#datatable_dlg_{$this->iListId}').dialog({autoOpen: false, title: '$sDlgTitle', width: 500, close: function() { $('#{$this->sDatatableContainerId}').datatable('onDlgCancel'); } });");
|
$oPage->add_ready_script("$('#datatable_dlg_{$this->iListId}').dialog({autoOpen: false, title: '$sDlgTitle', width: 500, close: function() { $('#{$this->sDatatableContainerId}').datatable('onDlgCancel'); } });");
|
||||||
|
|
||||||
@@ -458,7 +422,7 @@ EOF;
|
|||||||
*/
|
*/
|
||||||
public function GetAsHash($oSetting)
|
public function GetAsHash($oSetting)
|
||||||
{
|
{
|
||||||
$aSettings = array('iDefaultPageSize' => $oSetting->iDefaultPageSize, 'oColumns' => $oSetting->aColumns);
|
$aSettings = ['iDefaultPageSize' => $oSetting->iDefaultPageSize, 'oColumns' => $oSetting->aColumns];
|
||||||
return $aSettings;
|
return $aSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,55 +438,46 @@ EOF;
|
|||||||
*/
|
*/
|
||||||
protected function GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink)
|
protected function GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink)
|
||||||
{
|
{
|
||||||
$aAttribs = array();
|
$aAttribs = [];
|
||||||
if ($sSelectMode == 'multiple')
|
if ($sSelectMode == 'multiple') {
|
||||||
{
|
$aAttribs['form::select'] = [
|
||||||
$aAttribs['form::select'] = array(
|
|
||||||
'label' => "<input type=\"checkbox\" onClick=\"CheckAll('.selectList{$this->iListId}:not(:disabled)', this.checked);\" class=\"checkAll\"></input>",
|
'label' => "<input type=\"checkbox\" onClick=\"CheckAll('.selectList{$this->iListId}:not(:disabled)', this.checked);\" class=\"checkAll\"></input>",
|
||||||
'description' => Dict::S('UI:SelectAllToggle+'),
|
'description' => Dict::S('UI:SelectAllToggle+'),
|
||||||
'metadata' => array(),
|
'metadata' => [],
|
||||||
);
|
];
|
||||||
}
|
} elseif ($sSelectMode == 'single') {
|
||||||
else if ($sSelectMode == 'single')
|
$aAttribs['form::select'] = ['label' => '', 'description' => '', 'metadata' => []];
|
||||||
{
|
|
||||||
$aAttribs['form::select'] = array('label' => '', 'description' => '', 'metadata' => array());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($this->aClassAliases as $sAlias => $sClassName)
|
foreach ($this->aClassAliases as $sAlias => $sClassName) {
|
||||||
{
|
foreach ($aColumns[$sAlias] as $sAttCode => $aData) {
|
||||||
foreach($aColumns[$sAlias] as $sAttCode => $aData)
|
if ($aData['checked']) {
|
||||||
{
|
if ($sAttCode == '_key_') {
|
||||||
if ($aData['checked'])
|
|
||||||
{
|
|
||||||
if ($sAttCode == '_key_')
|
|
||||||
{
|
|
||||||
$sAttLabel = MetaModel::GetName($sClassName);
|
$sAttLabel = MetaModel::GetName($sClassName);
|
||||||
|
|
||||||
$aAttribs['key_'.$sAlias] = array(
|
$aAttribs['key_'.$sAlias] = [
|
||||||
'label' => $sAttLabel,
|
'label' => $sAttLabel,
|
||||||
'description' => '',
|
'description' => '',
|
||||||
'metadata' => array(
|
'metadata' => [
|
||||||
'object_class' => $sClassName,
|
'object_class' => $sClassName,
|
||||||
'attribute_label' => $sAttLabel,
|
'attribute_label' => $sAttLabel,
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClassName, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClassName, $sAttCode);
|
||||||
$sAttDefClass = get_class($oAttDef);
|
$sAttDefClass = get_class($oAttDef);
|
||||||
$sAttLabel = MetaModel::GetLabel($sClassName, $sAttCode);
|
$sAttLabel = MetaModel::GetLabel($sClassName, $sAttCode);
|
||||||
|
|
||||||
$aAttribs[$sAttCode.'_'.$sAlias] = array(
|
$aAttribs[$sAttCode.'_'.$sAlias] = [
|
||||||
'label' => $sAttLabel,
|
'label' => $sAttLabel,
|
||||||
'description' => $oAttDef->GetOrderByHint(),
|
'description' => $oAttDef->GetOrderByHint(),
|
||||||
'metadata' => array(
|
'metadata' => [
|
||||||
'object_class' => $sClassName,
|
'object_class' => $sClassName,
|
||||||
'attribute_code' => $sAttCode,
|
'attribute_code' => $sAttCode,
|
||||||
'attribute_type' => $sAttDefClass,
|
'attribute_type' => $sAttDefClass,
|
||||||
'attribute_label' => $sAttLabel,
|
'attribute_label' => $sAttLabel,
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -530,7 +485,6 @@ EOF;
|
|||||||
return $aAttribs;
|
return $aAttribs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $aColumns
|
* @param $aColumns
|
||||||
* @param $sSelectMode
|
* @param $sSelectMode
|
||||||
@@ -549,104 +503,74 @@ EOF;
|
|||||||
protected function GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
|
protected function GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
|
||||||
{
|
{
|
||||||
$bLocalize = true;
|
$bLocalize = true;
|
||||||
if (isset($aExtraParams['localize_values']))
|
if (isset($aExtraParams['localize_values'])) {
|
||||||
{
|
|
||||||
$bLocalize = (bool) $aExtraParams['localize_values'];
|
$bLocalize = (bool) $aExtraParams['localize_values'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$aValues = array();
|
$aValues = [];
|
||||||
$aAttDefsCache = array();
|
$aAttDefsCache = [];
|
||||||
$this->oSet->Seek(0);
|
$this->oSet->Seek(0);
|
||||||
$iMaxObjects = $iPageSize;
|
$iMaxObjects = $iPageSize;
|
||||||
while (($aObjects = $this->oSet->FetchAssoc()) && ($iMaxObjects != 0))
|
while (($aObjects = $this->oSet->FetchAssoc()) && ($iMaxObjects != 0)) {
|
||||||
{
|
|
||||||
$bFirstObject = true;
|
$bFirstObject = true;
|
||||||
$aRow = array();
|
$aRow = [];
|
||||||
foreach($this->aClassAliases as $sAlias => $sClassName)
|
foreach ($this->aClassAliases as $sAlias => $sClassName) {
|
||||||
{
|
if (is_object($aObjects[$sAlias])) {
|
||||||
if (is_object($aObjects[$sAlias]))
|
|
||||||
{
|
|
||||||
$sHilightClass = MetaModel::GetHilightClass($sClassName, $aObjects[$sAlias]);
|
$sHilightClass = MetaModel::GetHilightClass($sClassName, $aObjects[$sAlias]);
|
||||||
if ($sHilightClass != '')
|
if ($sHilightClass != '') {
|
||||||
{
|
$aRow['@class'] = $sHilightClass;
|
||||||
$aRow['@class'] = $sHilightClass;
|
|
||||||
}
|
}
|
||||||
if ((($sSelectMode == 'single') || ($sSelectMode == 'multiple')) && $bFirstObject)
|
if ((($sSelectMode == 'single') || ($sSelectMode == 'multiple')) && $bFirstObject) {
|
||||||
{
|
if (array_key_exists('selection_enabled', $aExtraParams) && isset($aExtraParams['selection_enabled'][$aObjects[$sAlias]->GetKey()])) {
|
||||||
if (array_key_exists('selection_enabled', $aExtraParams) && isset($aExtraParams['selection_enabled'][$aObjects[$sAlias]->GetKey()]))
|
|
||||||
{
|
|
||||||
$sDisabled = ($aExtraParams['selection_enabled'][$aObjects[$sAlias]->GetKey()]) ? '' : ' disabled="disabled"';
|
$sDisabled = ($aExtraParams['selection_enabled'][$aObjects[$sAlias]->GetKey()]) ? '' : ' disabled="disabled"';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sDisabled = '';
|
$sDisabled = '';
|
||||||
}
|
}
|
||||||
if ($sSelectMode == 'single')
|
if ($sSelectMode == 'single') {
|
||||||
{
|
|
||||||
$aRow['form::select'] = "<input type=\"radio\" $sDisabled class=\"selectList{$this->iListId}\" name=\"selectObject\" value=\"".$aObjects[$sAlias]->GetKey()."\"></input>";
|
$aRow['form::select'] = "<input type=\"radio\" $sDisabled class=\"selectList{$this->iListId}\" name=\"selectObject\" value=\"".$aObjects[$sAlias]->GetKey()."\"></input>";
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aRow['form::select'] = "<input type=\"checkbox\" $sDisabled class=\"selectList{$this->iListId}\" name=\"selectObject[]\" value=\"".$aObjects[$sAlias]->GetKey()."\"></input>";
|
$aRow['form::select'] = "<input type=\"checkbox\" $sDisabled class=\"selectList{$this->iListId}\" name=\"selectObject[]\" value=\"".$aObjects[$sAlias]->GetKey()."\"></input>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach($aColumns[$sAlias] as $sAttCode => $aData)
|
foreach ($aColumns[$sAlias] as $sAttCode => $aData) {
|
||||||
{
|
if ($aData['checked']) {
|
||||||
if ($aData['checked'])
|
if ($sAttCode == '_key_') {
|
||||||
{
|
$aRow['key_'.$sAlias] = [
|
||||||
if ($sAttCode == '_key_')
|
|
||||||
{
|
|
||||||
$aRow['key_'.$sAlias] = array(
|
|
||||||
'value_raw' => $aObjects[$sAlias]->GetKey(),
|
'value_raw' => $aObjects[$sAlias]->GetKey(),
|
||||||
'value_html' => $aObjects[$sAlias]->GetHyperLink(),
|
'value_html' => $aObjects[$sAlias]->GetHyperLink(),
|
||||||
);
|
];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Prepare att. def. classes cache to avoid retrieving AttDef for each row
|
// Prepare att. def. classes cache to avoid retrieving AttDef for each row
|
||||||
if(!isset($aAttDefsCache[$sClassName][$sAttCode]))
|
if (!isset($aAttDefsCache[$sClassName][$sAttCode])) {
|
||||||
{
|
|
||||||
$aAttDefClassesCache[$sClassName][$sAttCode] = get_class(MetaModel::GetAttributeDef($sClassName, $sAttCode));
|
$aAttDefClassesCache[$sClassName][$sAttCode] = get_class(MetaModel::GetAttributeDef($sClassName, $sAttCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only retrieve raw (stored) value for simple fields
|
// Only retrieve raw (stored) value for simple fields
|
||||||
$bExcludeRawValue = false;
|
$bExcludeRawValue = false;
|
||||||
foreach (cmdbAbstractObject::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude)
|
foreach (cmdbAbstractObject::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude) {
|
||||||
{
|
if (is_a($aAttDefClassesCache[$sClassName][$sAttCode], $sAttDefClassToExclude, true)) {
|
||||||
if (is_a($aAttDefClassesCache[$sClassName][$sAttCode], $sAttDefClassToExclude, true))
|
|
||||||
{
|
|
||||||
$bExcludeRawValue = true;
|
$bExcludeRawValue = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($bExcludeRawValue)
|
if ($bExcludeRawValue) {
|
||||||
{
|
|
||||||
$aRow[$sAttCode.'_'.$sAlias] = $aObjects[$sAlias]->GetAsHTML($sAttCode, $bLocalize);
|
$aRow[$sAttCode.'_'.$sAlias] = $aObjects[$sAlias]->GetAsHTML($sAttCode, $bLocalize);
|
||||||
}
|
} else {
|
||||||
else
|
$aRow[$sAttCode.'_'.$sAlias] = [
|
||||||
{
|
|
||||||
$aRow[$sAttCode.'_'.$sAlias] = array(
|
|
||||||
'value_raw' => $aObjects[$sAlias]->Get($sAttCode),
|
'value_raw' => $aObjects[$sAlias]->Get($sAttCode),
|
||||||
'value_html' => $aObjects[$sAlias]->GetAsHTML($sAttCode, $bLocalize),
|
'value_html' => $aObjects[$sAlias]->GetAsHTML($sAttCode, $bLocalize),
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
foreach ($aColumns[$sAlias] as $sAttCode => $aData) {
|
||||||
{
|
if ($aData['checked']) {
|
||||||
foreach($aColumns[$sAlias] as $sAttCode => $aData)
|
if ($sAttCode == '_key_') {
|
||||||
{
|
|
||||||
if ($aData['checked'])
|
|
||||||
{
|
|
||||||
if ($sAttCode == '_key_')
|
|
||||||
{
|
|
||||||
$aRow['key_'.$sAlias] = '';
|
$aRow['key_'.$sAlias] = '';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aRow[$sAttCode.'_'.$sAlias] = '';
|
$aRow[$sAttCode.'_'.$sAlias] = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -681,8 +605,7 @@ EOF;
|
|||||||
public function GetHTMLTable(WebPage $oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
|
public function GetHTMLTable(WebPage $oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
|
||||||
{
|
{
|
||||||
$iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize);
|
$iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize);
|
||||||
if ($iPageSize < 1)
|
if ($iPageSize < 1) {
|
||||||
{
|
|
||||||
$iPageSize = -1; // convention: no pagination
|
$iPageSize = -1; // convention: no pagination
|
||||||
}
|
}
|
||||||
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
||||||
@@ -691,8 +614,7 @@ EOF;
|
|||||||
|
|
||||||
$sHtml = '<table class="listContainer object-list">';
|
$sHtml = '<table class="listContainer object-list">';
|
||||||
|
|
||||||
foreach($this->oSet->GetFilter()->GetInternalParams() as $sName => $sValue)
|
foreach ($this->oSet->GetFilter()->GetInternalParams() as $sName => $sValue) {
|
||||||
{
|
|
||||||
$aExtraParams['query_params'][$sName] = $sValue;
|
$aExtraParams['query_params'][$sName] = $sValue;
|
||||||
}
|
}
|
||||||
$aExtraParams['show_obsolete_data'] = $this->bShowObsoleteData;
|
$aExtraParams['show_obsolete_data'] = $this->bShowObsoleteData;
|
||||||
@@ -707,20 +629,16 @@ EOF;
|
|||||||
$sExtraParams = addslashes(str_replace('"', "'", json_encode(array_merge($aExtraParams, $aArgs)))); // JSON encode, change the style of the quotes and escape them
|
$sExtraParams = addslashes(str_replace('"', "'", json_encode(array_merge($aExtraParams, $aArgs)))); // JSON encode, change the style of the quotes and escape them
|
||||||
$sSelectModeJS = '';
|
$sSelectModeJS = '';
|
||||||
$sHeaders = '';
|
$sHeaders = '';
|
||||||
if (($sSelectMode == 'single') || ($sSelectMode == 'multiple'))
|
if (($sSelectMode == 'single') || ($sSelectMode == 'multiple')) {
|
||||||
{
|
|
||||||
$sSelectModeJS = $sSelectMode;
|
$sSelectModeJS = $sSelectMode;
|
||||||
$sHeaders = 'headers: { 0: {sorter: false}},';
|
$sHeaders = 'headers: { 0: {sorter: false}},';
|
||||||
}
|
}
|
||||||
$sDisplayKey = ($bViewLink) ? 'true' : 'false';
|
$sDisplayKey = ($bViewLink) ? 'true' : 'false';
|
||||||
// Protect against duplicate elements in the Zlist
|
// Protect against duplicate elements in the Zlist
|
||||||
$aUniqueOrderedList = array();
|
$aUniqueOrderedList = [];
|
||||||
foreach($this->aClassAliases as $sAlias => $sClassName)
|
foreach ($this->aClassAliases as $sAlias => $sClassName) {
|
||||||
{
|
foreach ($aColumns[$sAlias] as $sAttCode => $aData) {
|
||||||
foreach($aColumns[$sAlias] as $sAttCode => $aData)
|
if ($aData['checked']) {
|
||||||
{
|
|
||||||
if ($aData['checked'])
|
|
||||||
{
|
|
||||||
$aUniqueOrderedList[$sAttCode] = true;
|
$aUniqueOrderedList[$sAttCode] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -732,41 +650,32 @@ EOF;
|
|||||||
$this->oSet->ApplyParameters();
|
$this->oSet->ApplyParameters();
|
||||||
// Display the actual sort order of the table
|
// Display the actual sort order of the table
|
||||||
$aRealSortOrder = $this->oSet->GetRealSortOrder();
|
$aRealSortOrder = $this->oSet->GetRealSortOrder();
|
||||||
$aDefaultSort = array();
|
$aDefaultSort = [];
|
||||||
$iColOffset = 0;
|
$iColOffset = 0;
|
||||||
if (($sSelectMode == 'single') || ($sSelectMode == 'multiple'))
|
if (($sSelectMode == 'single') || ($sSelectMode == 'multiple')) {
|
||||||
{
|
|
||||||
$iColOffset += 1;
|
$iColOffset += 1;
|
||||||
}
|
}
|
||||||
if ($bViewLink)
|
if ($bViewLink) {
|
||||||
{
|
// $iColOffset += 1;
|
||||||
// $iColOffset += 1;
|
|
||||||
}
|
}
|
||||||
foreach($aRealSortOrder as $sColCode => $bAscending)
|
foreach ($aRealSortOrder as $sColCode => $bAscending) {
|
||||||
{
|
|
||||||
$iPos = array_search($sColCode, $aUniqueOrderedList);
|
$iPos = array_search($sColCode, $aUniqueOrderedList);
|
||||||
if ($iPos !== false)
|
if ($iPos !== false) {
|
||||||
{
|
$aDefaultSort[] = "[".($iColOffset + $iPos).",".($bAscending ? '0' : '1')."]";
|
||||||
$aDefaultSort[] = "[".($iColOffset+$iPos).",".($bAscending ? '0' : '1')."]";
|
} elseif (($iPos = array_search(preg_replace('/_friendlyname$/', '', $sColCode), $aUniqueOrderedList)) !== false) {
|
||||||
}
|
|
||||||
else if (($iPos = array_search(preg_replace('/_friendlyname$/', '', $sColCode), $aUniqueOrderedList)) !== false)
|
|
||||||
{
|
|
||||||
// if sorted on the friendly name of an external key, then consider it sorted on the column that shows the links
|
// if sorted on the friendly name of an external key, then consider it sorted on the column that shows the links
|
||||||
$aDefaultSort[] = "[".($iColOffset+$iPos).",".($bAscending ? '0' : '1')."]";
|
$aDefaultSort[] = "[".($iColOffset + $iPos).",".($bAscending ? '0' : '1')."]";
|
||||||
}
|
} elseif ($sColCode == 'friendlyname' && $bViewLink) {
|
||||||
else if($sColCode == 'friendlyname' && $bViewLink)
|
|
||||||
{
|
|
||||||
$aDefaultSort[] = "[".($iColOffset).",".($bAscending ? '0' : '1')."]";
|
$aDefaultSort[] = "[".($iColOffset).",".($bAscending ? '0' : '1')."]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$sFakeSortList = '';
|
$sFakeSortList = '';
|
||||||
if (count($aDefaultSort) > 0)
|
if (count($aDefaultSort) > 0) {
|
||||||
{
|
|
||||||
$sFakeSortList = '['.implode(',', $aDefaultSort).']';
|
$sFakeSortList = '['.implode(',', $aDefaultSort).']';
|
||||||
}
|
}
|
||||||
$sOQL = addslashes($this->oSet->GetFilter()->serialize());
|
$sOQL = addslashes($this->oSet->GetFilter()->serialize());
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<JS
|
<<<JS
|
||||||
var oTable = $('#{$this->sDatatableContainerId} table.listResults');
|
var oTable = $('#{$this->sDatatableContainerId} table.listResults');
|
||||||
oTable.tableHover();
|
oTable.tableHover();
|
||||||
oTable
|
oTable
|
||||||
@@ -784,9 +693,8 @@ oTable
|
|||||||
class_aliases: $sJSClassAliases $sCssCount
|
class_aliases: $sJSClassAliases $sCssCount
|
||||||
});
|
});
|
||||||
JS
|
JS
|
||||||
);
|
);
|
||||||
if ($sFakeSortList != '')
|
if ($sFakeSortList != '') {
|
||||||
{
|
|
||||||
$oPage->add_ready_script("oTable.trigger(\"fakesorton\", [$sFakeSortList]);");
|
$oPage->add_ready_script("oTable.trigger(\"fakesorton\", [$sFakeSortList]);");
|
||||||
}
|
}
|
||||||
return $sHtml;
|
return $sHtml;
|
||||||
@@ -803,12 +711,9 @@ JS
|
|||||||
$iPageIndex = 0;
|
$iPageIndex = 0;
|
||||||
$sHtml = $this->GetPager($oPage, $iPageSize, $iDefaultPageSize, $iPageIndex);
|
$sHtml = $this->GetPager($oPage, $iPageSize, $iDefaultPageSize, $iPageIndex);
|
||||||
$oPage->add_ready_script("$('#pager{$this->iListId}').html('".json_encode($sHtml)."');");
|
$oPage->add_ready_script("$('#pager{$this->iListId}').html('".json_encode($sHtml)."');");
|
||||||
if ($iDefaultPageSize < 1)
|
if ($iDefaultPageSize < 1) {
|
||||||
{
|
|
||||||
$oPage->add_ready_script("$('#pager{$this->iListId}').parent().hide()");
|
$oPage->add_ready_script("$('#pager{$this->iListId}').parent().hide()");
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oPage->add_ready_script("$('#pager{$this->iListId}').parent().show()");
|
$oPage->add_ready_script("$('#pager{$this->iListId}').parent().show()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -865,16 +770,15 @@ class PrintableDataTable extends DataTable
|
|||||||
public function GetHTMLTable(WebPage $oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
|
public function GetHTMLTable(WebPage $oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
|
||||||
{
|
{
|
||||||
$iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize);
|
$iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize);
|
||||||
if ($iPageSize < 1)
|
if ($iPageSize < 1) {
|
||||||
{
|
|
||||||
$iPageSize = -1; // convention: no pagination
|
$iPageSize = -1; // convention: no pagination
|
||||||
}
|
}
|
||||||
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
||||||
|
|
||||||
$aValues = $this->GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
$aValues = $this->GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
||||||
|
|
||||||
$sHtml = $oPage->GetTable($aAttribs, $aValues);
|
$sHtml = $oPage->GetTable($aAttribs, $aValues);
|
||||||
|
|
||||||
return $sHtml;
|
return $sHtml;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -104,7 +105,7 @@ class DisplayBlock
|
|||||||
*/
|
*/
|
||||||
public const ENUM_STYLE_CHART_AJAX = 'chart_ajax';
|
public const ENUM_STYLE_CHART_AJAX = 'chart_ajax';
|
||||||
|
|
||||||
const TAG_BLOCK = 'itopblock';
|
public const TAG_BLOCK = 'itopblock';
|
||||||
/** @var \DBSearch */
|
/** @var \DBSearch */
|
||||||
protected $m_oFilter;
|
protected $m_oFilter;
|
||||||
protected $m_aConditions; // Conditions added to the filter -> avoid duplicate conditions
|
protected $m_aConditions; // Conditions added to the filter -> avoid duplicate conditions
|
||||||
@@ -137,20 +138,18 @@ class DisplayBlock
|
|||||||
*
|
*
|
||||||
* @throws \ApplicationException
|
* @throws \ApplicationException
|
||||||
*/
|
*/
|
||||||
public function __construct(DBSearch $oFilter, $sStyle = self::ENUM_STYLE_LIST, $bAsynchronous = false, $aParams = array(), $oSet = null)
|
public function __construct(DBSearch $oFilter, $sStyle = self::ENUM_STYLE_LIST, $bAsynchronous = false, $aParams = [], $oSet = null)
|
||||||
{
|
{
|
||||||
$this->m_oFilter = $oFilter->DeepClone();
|
$this->m_oFilter = $oFilter->DeepClone();
|
||||||
$this->m_aConditions = array();
|
$this->m_aConditions = [];
|
||||||
$this->m_sStyle = $sStyle;
|
$this->m_sStyle = $sStyle;
|
||||||
$this->m_bAsynchronous = $bAsynchronous;
|
$this->m_bAsynchronous = $bAsynchronous;
|
||||||
$this->m_aParams = $aParams;
|
$this->m_aParams = $aParams;
|
||||||
$this->m_oSet = $oSet;
|
$this->m_oSet = $oSet;
|
||||||
if (array_key_exists('show_obsolete_data', $aParams))
|
if (array_key_exists('show_obsolete_data', $aParams)) {
|
||||||
{
|
|
||||||
$this->m_bShowObsoleteData = $aParams['show_obsolete_data'];
|
$this->m_bShowObsoleteData = $aParams['show_obsolete_data'];
|
||||||
}
|
}
|
||||||
if ($this->m_bShowObsoleteData === null)
|
if ($this->m_bShowObsoleteData === null) {
|
||||||
{
|
|
||||||
// User defined
|
// User defined
|
||||||
$this->m_bShowObsoleteData = utils::ShowObsoleteData();
|
$this->m_bShowObsoleteData = utils::ShowObsoleteData();
|
||||||
}
|
}
|
||||||
@@ -410,22 +409,18 @@ class DisplayBlock
|
|||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function FromObjectSet(DBObjectSet $oSet, $sStyle, $aParams = array())
|
public static function FromObjectSet(DBObjectSet $oSet, $sStyle, $aParams = [])
|
||||||
{
|
{
|
||||||
$oDummyFilter = new DBObjectSearch($oSet->GetClass());
|
$oDummyFilter = new DBObjectSearch($oSet->GetClass());
|
||||||
$aKeys = array();
|
$aKeys = [];
|
||||||
$oSet->OptimizeColumnLoad(array($oSet->GetClassAlias() => array())); // No need to load all the columns just to get the id
|
$oSet->OptimizeColumnLoad([$oSet->GetClassAlias() => []]); // No need to load all the columns just to get the id
|
||||||
while($oObject = $oSet->Fetch())
|
while ($oObject = $oSet->Fetch()) {
|
||||||
{
|
$aKeys[] = $oObject->GetKey();
|
||||||
$aKeys[] = $oObject->GetKey();
|
|
||||||
}
|
}
|
||||||
$oSet->Rewind();
|
$oSet->Rewind();
|
||||||
if (count($aKeys) > 0)
|
if (count($aKeys) > 0) {
|
||||||
{
|
|
||||||
$oDummyFilter->AddCondition('id', $aKeys, 'IN');
|
$oDummyFilter->AddCondition('id', $aKeys, 'IN');
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oDummyFilter->AddCondition('id', 0, '=');
|
$oDummyFilter->AddCondition('id', 0, '=');
|
||||||
}
|
}
|
||||||
$oBlock = new DisplayBlock($oDummyFilter, $sStyle, false, $aParams); // DisplayBlocks built this way are synchronous
|
$oBlock = new DisplayBlock($oDummyFilter, $sStyle, false, $aParams); // DisplayBlocks built this way are synchronous
|
||||||
@@ -446,7 +441,7 @@ class DisplayBlock
|
|||||||
$iStartPos = stripos($sTemplate, '<'.self::TAG_BLOCK.' ', 0);
|
$iStartPos = stripos($sTemplate, '<'.self::TAG_BLOCK.' ', 0);
|
||||||
$iEndPos = stripos($sTemplate, '</'.self::TAG_BLOCK.'>', $iStartPos);
|
$iEndPos = stripos($sTemplate, '</'.self::TAG_BLOCK.'>', $iStartPos);
|
||||||
$iEndTag = stripos($sTemplate, '>', $iStartPos);
|
$iEndTag = stripos($sTemplate, '>', $iStartPos);
|
||||||
$aParams = array();
|
$aParams = [];
|
||||||
|
|
||||||
if (($iStartPos === false) || ($iEndPos === false)) {
|
if (($iStartPos === false) || ($iEndPos === false)) {
|
||||||
return null;
|
return null;
|
||||||
@@ -454,7 +449,7 @@ class DisplayBlock
|
|||||||
$sITopData = substr($sTemplate, 1 + $iEndTag, $iEndPos - $iEndTag - 1);
|
$sITopData = substr($sTemplate, 1 + $iEndTag, $iEndPos - $iEndTag - 1);
|
||||||
$sITopTag = substr($sTemplate, $iStartPos + strlen('<'.self::TAG_BLOCK), $iEndTag - $iStartPos - strlen('<'.self::TAG_BLOCK));
|
$sITopTag = substr($sTemplate, $iStartPos + strlen('<'.self::TAG_BLOCK), $iEndTag - $iStartPos - strlen('<'.self::TAG_BLOCK));
|
||||||
|
|
||||||
$aMatches = array();
|
$aMatches = [];
|
||||||
$sBlockClass = "DisplayBlock";
|
$sBlockClass = "DisplayBlock";
|
||||||
$bAsynchronous = false;
|
$bAsynchronous = false;
|
||||||
$sBlockType = 'list';
|
$sBlockType = 'list';
|
||||||
@@ -520,25 +515,28 @@ class DisplayBlock
|
|||||||
return new $sBlockClass($oFilter, $sBlockType, $bAsynchronous, $aParams);
|
return new $sBlockClass($oFilter, $sBlockType, $bAsynchronous, $aParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function DisplayIntoContentBlock(UIContentBlock $oContentBlock, WebPage $oPage, $sId, $aExtraParams = array())
|
public function DisplayIntoContentBlock(UIContentBlock $oContentBlock, WebPage $oPage, $sId, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
$oContentBlock->AddSubBlock($this->GetDisplay($oPage, $sId, $aExtraParams));
|
$oContentBlock->AddSubBlock($this->GetDisplay($oPage, $sId, $aExtraParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Display(WebPage $oPage, $sId, $aExtraParams = array())
|
public function Display(WebPage $oPage, $sId, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
$oPage->AddUiBlock($this->GetDisplay($oPage, $sId, $aExtraParams));
|
$oPage->AddUiBlock($this->GetDisplay($oPage, $sId, $aExtraParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetDisplay(WebPage $oPage, $sId, $aExtraParams = array()): UIContentBlock
|
public function GetDisplay(WebPage $oPage, $sId, $aExtraParams = []): UIContentBlock
|
||||||
{
|
{
|
||||||
$oHtml = new UIContentBlock($sId);
|
$oHtml = new UIContentBlock($sId);
|
||||||
|
|
||||||
$oHtml->AddCSSClass("display_block");
|
$oHtml->AddCSSClass("display_block");
|
||||||
$aExtraParams = array_merge($aExtraParams, $this->m_aParams);
|
$aExtraParams = array_merge($aExtraParams, $this->m_aParams);
|
||||||
$aExtraParams['currentId'] = $sId;
|
$aExtraParams['currentId'] = $sId;
|
||||||
$sExtraParams = addslashes(str_replace('"', "'",
|
$sExtraParams = addslashes(str_replace(
|
||||||
json_encode($aExtraParams))); // JSON encode, change the style of the quotes and escape them
|
'"',
|
||||||
|
"'",
|
||||||
|
json_encode($aExtraParams)
|
||||||
|
)); // JSON encode, change the style of the quotes and escape them
|
||||||
|
|
||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
@@ -547,9 +545,9 @@ class DisplayBlock
|
|||||||
$sClass = $aExtraParams['this->class'];
|
$sClass = $aExtraParams['this->class'];
|
||||||
$iKey = $aExtraParams['this->id'];
|
$iKey = $aExtraParams['this->id'];
|
||||||
$oObj = MetaModel::GetObject($sClass, $iKey);
|
$oObj = MetaModel::GetObject($sClass, $iKey);
|
||||||
$aQueryParams = array('this->object()' => $oObj);
|
$aQueryParams = ['this->object()' => $oObj];
|
||||||
} else {
|
} else {
|
||||||
$aQueryParams = array();
|
$aQueryParams = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -585,8 +583,7 @@ class DisplayBlock
|
|||||||
');
|
');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->m_sStyle == static::ENUM_STYLE_LIST) // Search form need to extract result list extra data, the simplest way is to expose this configuration
|
if ($this->m_sStyle == static::ENUM_STYLE_LIST) { // Search form need to extract result list extra data, the simplest way is to expose this configuration
|
||||||
{
|
|
||||||
$listJsonExtraParams = json_encode(json_encode($aExtraParams));
|
$listJsonExtraParams = json_encode(json_encode($aExtraParams));
|
||||||
$oPage->add_ready_script("
|
$oPage->add_ready_script("
|
||||||
$('#$sId').data('sExtraParams', ".$listJsonExtraParams.");
|
$('#$sId').data('sExtraParams', ".$listJsonExtraParams.");
|
||||||
@@ -606,7 +603,7 @@ class DisplayBlock
|
|||||||
* @throws \DictExceptionMissingString
|
* @throws \DictExceptionMissingString
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
if (!isset($aExtraParams['currentId'])) {
|
if (!isset($aExtraParams['currentId'])) {
|
||||||
$sId = utils::GetUniqueId(); // Works only if the page is not an Ajax one !
|
$sId = utils::GetUniqueId(); // Works only if the page is not an Ajax one !
|
||||||
@@ -638,7 +635,7 @@ class DisplayBlock
|
|||||||
$this->CheckParams($this->m_sStyle, $aExtraParams);
|
$this->CheckParams($this->m_sStyle, $aExtraParams);
|
||||||
// Add the extra params into the filter if they make sense for such a filter
|
// Add the extra params into the filter if they make sense for such a filter
|
||||||
$bDoSearch = utils::ReadParam('dosearch', false);
|
$bDoSearch = utils::ReadParam('dosearch', false);
|
||||||
$aQueryParams = array();
|
$aQueryParams = [];
|
||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
} else {
|
} else {
|
||||||
@@ -646,7 +643,7 @@ class DisplayBlock
|
|||||||
$sClass = $aExtraParams['this->class'];
|
$sClass = $aExtraParams['this->class'];
|
||||||
$iKey = $aExtraParams['this->id'];
|
$iKey = $aExtraParams['this->id'];
|
||||||
$oObj = MetaModel::GetObject($sClass, $iKey);
|
$oObj = MetaModel::GetObject($sClass, $iKey);
|
||||||
$aQueryParams = array('this->object()' => $oObj);
|
$aQueryParams = ['this->object()' => $oObj];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->m_oSet == null) {
|
if ($this->m_oSet == null) {
|
||||||
@@ -656,7 +653,7 @@ class DisplayBlock
|
|||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sClass = $this->m_oFilter->GetClass();
|
$sClass = $this->m_oFilter->GetClass();
|
||||||
$aFilterCodes = MetaModel::GetFiltersList($sClass);
|
$aFilterCodes = MetaModel::GetFiltersList($sClass);
|
||||||
$aCallSpec = array($sClass, 'MapContextParam');
|
$aCallSpec = [$sClass, 'MapContextParam'];
|
||||||
if (is_callable($aCallSpec)) {
|
if (is_callable($aCallSpec)) {
|
||||||
foreach ($oAppContext->GetNames() as $sContextParam) {
|
foreach ($oAppContext->GetNames() as $sContextParam) {
|
||||||
$sParamCode = call_user_func($aCallSpec, $sContextParam); //Map context parameter to the value/filter code depending on the class
|
$sParamCode = call_user_func($aCallSpec, $sContextParam); //Map context parameter to the value/filter code depending on the class
|
||||||
@@ -691,11 +688,9 @@ class DisplayBlock
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_null($condition))
|
if (!is_null($condition)) {
|
||||||
{
|
|
||||||
$sOpCode = null; // default operator
|
$sOpCode = null; // default operator
|
||||||
if (is_array($condition))
|
if (is_array($condition)) {
|
||||||
{
|
|
||||||
// Multiple values, add them as AND X IN (v1, v2, v3...)
|
// Multiple values, add them as AND X IN (v1, v2, v3...)
|
||||||
$sOpCode = 'IN';
|
$sOpCode = 'IN';
|
||||||
}
|
}
|
||||||
@@ -703,26 +698,22 @@ class DisplayBlock
|
|||||||
$this->AddCondition($sFilterCode, $condition, $sOpCode, $bParseSearchString);
|
$this->AddCondition($sFilterCode, $condition, $sOpCode, $bParseSearchString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($bDoSearch)
|
if ($bDoSearch) {
|
||||||
{
|
|
||||||
// Keep the table_id identifying this table if we're performing a search
|
// Keep the table_id identifying this table if we're performing a search
|
||||||
$sTableId = utils::ReadParam('_table_id_', null, false, utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
$sTableId = utils::ReadParam('_table_id_', null, false, utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
||||||
if ($sTableId != null)
|
if ($sTableId != null) {
|
||||||
{
|
|
||||||
$aExtraParams['table_id'] = $sTableId;
|
$aExtraParams['table_id'] = $sTableId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aOrderBy = array();
|
$aOrderBy = [];
|
||||||
if (isset($aExtraParams['order_by']))
|
if (isset($aExtraParams['order_by'])) {
|
||||||
{
|
|
||||||
// Convert the string describing the order_by parameter into an array
|
// Convert the string describing the order_by parameter into an array
|
||||||
// The syntax is +attCode1,-attCode2
|
// The syntax is +attCode1,-attCode2
|
||||||
// attCode1 => ascending, attCode2 => descending
|
// attCode1 => ascending, attCode2 => descending
|
||||||
$aTemp = explode(',', $aExtraParams['order_by']);
|
$aTemp = explode(',', $aExtraParams['order_by']);
|
||||||
foreach($aTemp as $sTemp)
|
foreach ($aTemp as $sTemp) {
|
||||||
{
|
$aMatches = [];
|
||||||
$aMatches = array();
|
|
||||||
if (preg_match('/^([+-])?(.+)$/', $sTemp, $aMatches)) {
|
if (preg_match('/^([+-])?(.+)$/', $sTemp, $aMatches)) {
|
||||||
$bAscending = true;
|
$bAscending = true;
|
||||||
if ($aMatches[1] == '-') {
|
if ($aMatches[1] == '-') {
|
||||||
@@ -738,7 +729,7 @@ class DisplayBlock
|
|||||||
}
|
}
|
||||||
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
||||||
|
|
||||||
switch($this->m_sStyle) {
|
switch ($this->m_sStyle) {
|
||||||
case static::ENUM_STYLE_LIST_SEARCH:
|
case static::ENUM_STYLE_LIST_SEARCH:
|
||||||
case static::ENUM_STYLE_LIST:
|
case static::ENUM_STYLE_LIST:
|
||||||
break;
|
break;
|
||||||
@@ -768,7 +759,7 @@ class DisplayBlock
|
|||||||
case static::ENUM_STYLE_LIST:
|
case static::ENUM_STYLE_LIST:
|
||||||
case static::ENUM_STYLE_LIST_IN_OBJECT:
|
case static::ENUM_STYLE_LIST_IN_OBJECT:
|
||||||
$oBlock = $this->RenderList($aExtraParams, $oPage);
|
$oBlock = $this->RenderList($aExtraParams, $oPage);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'links':
|
case 'links':
|
||||||
$oBlock = $this->RenderLinks($oPage, $aExtraParams);
|
$oBlock = $this->RenderLinks($oPage, $aExtraParams);
|
||||||
@@ -793,53 +784,45 @@ class DisplayBlock
|
|||||||
case static::ENUM_STYLE_CHART:
|
case static::ENUM_STYLE_CHART:
|
||||||
$oBlock = $this->RenderChart($sId, $aQueryParams, $aExtraParams);
|
$oBlock = $this->RenderChart($sId, $aQueryParams, $aExtraParams);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case static::ENUM_STYLE_CHART_AJAX:
|
case static::ENUM_STYLE_CHART_AJAX:
|
||||||
$oBlock = $this->RenderChartAjax($aExtraParams);
|
$oBlock = $this->RenderChartAjax($aExtraParams);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Unsupported style, do nothing.
|
// Unsupported style, do nothing.
|
||||||
$sHtml .= Dict::format('UI:Error:UnsupportedStyleOfBlock', $this->m_sStyle);
|
$sHtml .= Dict::format('UI:Error:UnsupportedStyleOfBlock', $this->m_sStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$bAutoReload = false;
|
$bAutoReload = false;
|
||||||
if (isset($aExtraParams['auto_reload']))
|
if (isset($aExtraParams['auto_reload'])) {
|
||||||
{
|
if ($aExtraParams['auto_reload'] === true) {
|
||||||
if ($aExtraParams['auto_reload'] === true)
|
|
||||||
{
|
|
||||||
// Note: does not work in the switch (case true) because a positive number evaluates to true!!!
|
// Note: does not work in the switch (case true) because a positive number evaluates to true!!!
|
||||||
$aExtraParams['auto_reload'] = 'standard';
|
$aExtraParams['auto_reload'] = 'standard';
|
||||||
}
|
}
|
||||||
switch($aExtraParams['auto_reload'])
|
switch ($aExtraParams['auto_reload']) {
|
||||||
{
|
|
||||||
case 'fast':
|
case 'fast':
|
||||||
$bAutoReload = true;
|
$bAutoReload = true;
|
||||||
$iReloadInterval = MetaModel::GetConfig()->GetFastReloadInterval()*1000;
|
$iReloadInterval = MetaModel::GetConfig()->GetFastReloadInterval() * 1000;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'standard':
|
case 'standard':
|
||||||
case 'true':
|
case 'true':
|
||||||
$bAutoReload = true;
|
$bAutoReload = true;
|
||||||
$iReloadInterval = MetaModel::GetConfig()->GetStandardReloadInterval()*1000;
|
$iReloadInterval = MetaModel::GetConfig()->GetStandardReloadInterval() * 1000;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (is_numeric($aExtraParams['auto_reload']) && ($aExtraParams['auto_reload'] > 0))
|
if (is_numeric($aExtraParams['auto_reload']) && ($aExtraParams['auto_reload'] > 0)) {
|
||||||
{
|
|
||||||
$bAutoReload = true;
|
$bAutoReload = true;
|
||||||
$iReloadInterval = max(MetaModel::GetConfig()->Get('min_reload_interval'), $aExtraParams['auto_reload'])*1000;
|
$iReloadInterval = max(MetaModel::GetConfig()->Get('min_reload_interval'), $aExtraParams['auto_reload']) * 1000;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// incorrect config, ignore it
|
// incorrect config, ignore it
|
||||||
$bAutoReload = false;
|
$bAutoReload = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (($bAutoReload) && ($this->m_sStyle != static::ENUM_STYLE_SEARCH)) // Search form do NOT auto-reload
|
if (($bAutoReload) && ($this->m_sStyle != static::ENUM_STYLE_SEARCH)) { // Search form do NOT auto-reload
|
||||||
{
|
|
||||||
// Used either for asynchronous or auto_reload
|
// Used either for asynchronous or auto_reload
|
||||||
// does a json_encode twice to get a string usable as function parameter
|
// does a json_encode twice to get a string usable as function parameter
|
||||||
$sFilterBefore = $this->m_oFilter->serialize();
|
$sFilterBefore = $this->m_oFilter->serialize();
|
||||||
@@ -886,8 +869,7 @@ JS
|
|||||||
{
|
{
|
||||||
// Workaround to an issue revealed whenever a condition on org_id is applied twice (with a hierarchy of organizations)
|
// Workaround to an issue revealed whenever a condition on org_id is applied twice (with a hierarchy of organizations)
|
||||||
// Moreover, it keeps the query as simple as possible
|
// Moreover, it keeps the query as simple as possible
|
||||||
if (isset($this->m_aConditions[$sFilterCode]) && $condition == $this->m_aConditions[$sFilterCode])
|
if (isset($this->m_aConditions[$sFilterCode]) && $condition == $this->m_aConditions[$sFilterCode]) {
|
||||||
{
|
|
||||||
// Skip
|
// Skip
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -895,59 +877,48 @@ JS
|
|||||||
|
|
||||||
$sClass = $this->m_oFilter->GetClass();
|
$sClass = $this->m_oFilter->GetClass();
|
||||||
$bConditionAdded = false;
|
$bConditionAdded = false;
|
||||||
|
|
||||||
// If the condition is an external key with a class having a hierarchy, use a "below" criteria
|
// If the condition is an external key with a class having a hierarchy, use a "below" criteria
|
||||||
if (MetaModel::IsValidAttCode($sClass, $sFilterCode))
|
if (MetaModel::IsValidAttCode($sClass, $sFilterCode)) {
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sFilterCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sFilterCode);
|
||||||
|
|
||||||
if ($oAttDef->IsExternalKey())
|
if ($oAttDef->IsExternalKey()) {
|
||||||
{
|
|
||||||
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($oAttDef->GetTargetClass());
|
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($oAttDef->GetTargetClass());
|
||||||
|
|
||||||
if ($sHierarchicalKeyCode !== false)
|
if ($sHierarchicalKeyCode !== false) {
|
||||||
{
|
|
||||||
$oFilter = new DBObjectSearch($oAttDef->GetTargetClass());
|
$oFilter = new DBObjectSearch($oAttDef->GetTargetClass());
|
||||||
if (($sOpCode == 'IN') && is_array($condition))
|
if (($sOpCode == 'IN') && is_array($condition)) {
|
||||||
{
|
$oFilter->AddConditionExpression(self::GetConditionIN($oFilter, 'id', $condition));
|
||||||
$oFilter->AddConditionExpression(self::GetConditionIN($oFilter, 'id', $condition));
|
} else {
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$oFilter->AddCondition('id', $condition);
|
$oFilter->AddCondition('id', $condition);
|
||||||
}
|
}
|
||||||
$oHKFilter = new DBObjectSearch($oAttDef->GetTargetClass());
|
$oHKFilter = new DBObjectSearch($oAttDef->GetTargetClass());
|
||||||
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW); // Use the 'below' operator by default
|
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW); // Use the 'below' operator by default
|
||||||
$this->m_oFilter->AddCondition_PointingTo($oHKFilter, $sFilterCode);
|
$this->m_oFilter->AddCondition_PointingTo($oHKFilter, $sFilterCode);
|
||||||
$bConditionAdded = true;
|
$bConditionAdded = true;
|
||||||
}
|
} elseif (($sOpCode == 'IN') && is_array($condition)) {
|
||||||
else if (($sOpCode == 'IN') && is_array($condition))
|
|
||||||
{
|
|
||||||
$this->m_oFilter->AddConditionExpression(self::GetConditionIN($this->m_oFilter, $sFilterCode, $condition));
|
$this->m_oFilter->AddConditionExpression(self::GetConditionIN($this->m_oFilter, $sFilterCode, $condition));
|
||||||
$bConditionAdded = true;
|
$bConditionAdded = true;
|
||||||
}
|
}
|
||||||
}
|
} elseif (($sOpCode == 'IN') && is_array($condition)) {
|
||||||
else if (($sOpCode == 'IN') && is_array($condition))
|
|
||||||
{
|
|
||||||
$this->m_oFilter->AddConditionExpression(self::GetConditionIN($this->m_oFilter, $sFilterCode, $condition));
|
$this->m_oFilter->AddConditionExpression(self::GetConditionIN($this->m_oFilter, $sFilterCode, $condition));
|
||||||
$bConditionAdded = true;
|
$bConditionAdded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// In all other cases, just add the condition directly
|
// In all other cases, just add the condition directly
|
||||||
if (!$bConditionAdded)
|
if (!$bConditionAdded) {
|
||||||
{
|
|
||||||
$this->m_oFilter->AddCondition($sFilterCode, $condition, null); // Use the default 'loose' operator
|
$this->m_oFilter->AddCondition($sFilterCode, $condition, null); // Use the default 'loose' operator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static protected function GetConditionIN($oFilter, $sFilterCode, $condition)
|
protected static function GetConditionIN($oFilter, $sFilterCode, $condition)
|
||||||
{
|
{
|
||||||
$oField = new FieldExpression($sFilterCode, $oFilter->GetClassAlias());
|
$oField = new FieldExpression($sFilterCode, $oFilter->GetClassAlias());
|
||||||
$sListExpr = '('.implode(', ', CMDBSource::Quote($condition)).')';
|
$sListExpr = '('.implode(', ', CMDBSource::Quote($condition)).')';
|
||||||
$sOQLCondition = $oField->RenderExpression()." IN $sListExpr";
|
$sOQLCondition = $oField->RenderExpression()." IN $sListExpr";
|
||||||
$oNewCondition = Expression::FromOQL($sOQLCondition);
|
$oNewCondition = Expression::FromOQL($sOQLCondition);
|
||||||
return $oNewCondition;
|
return $oNewCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -974,13 +945,10 @@ JS
|
|||||||
protected function MakeGroupByQuery(&$aExtraParams, &$oGroupByExp, &$sGroupByLabel, &$aGroupBy, &$sAggregationFunction, &$sFctVar, &$sAggregationAttr, &$sSql)
|
protected function MakeGroupByQuery(&$aExtraParams, &$oGroupByExp, &$sGroupByLabel, &$aGroupBy, &$sAggregationFunction, &$sFctVar, &$sAggregationAttr, &$sSql)
|
||||||
{
|
{
|
||||||
$sAlias = $this->m_oFilter->GetClassAlias();
|
$sAlias = $this->m_oFilter->GetClassAlias();
|
||||||
if (isset($aExtraParams['group_by_label']))
|
if (isset($aExtraParams['group_by_label'])) {
|
||||||
{
|
|
||||||
$oGroupByExp = Expression::FromOQL($aExtraParams['group_by']);
|
$oGroupByExp = Expression::FromOQL($aExtraParams['group_by']);
|
||||||
$sGroupByLabel = $aExtraParams['group_by_label'];
|
$sGroupByLabel = $aExtraParams['group_by_label'];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Backward compatibility: group_by is simply a field id
|
// Backward compatibility: group_by is simply a field id
|
||||||
$oGroupByExp = new FieldExpression($aExtraParams['group_by'], $sAlias);
|
$oGroupByExp = new FieldExpression($aExtraParams['group_by'], $sAlias);
|
||||||
$sGroupByLabel = MetaModel::GetLabel($this->m_oFilter->GetClass(), $aExtraParams['group_by']);
|
$sGroupByLabel = MetaModel::GetLabel($this->m_oFilter->GetClass(), $aExtraParams['group_by']);
|
||||||
@@ -988,61 +956,52 @@ JS
|
|||||||
|
|
||||||
// Security filtering
|
// Security filtering
|
||||||
$aFields = $oGroupByExp->ListRequiredFields();
|
$aFields = $oGroupByExp->ListRequiredFields();
|
||||||
foreach($aFields as $sFieldAlias)
|
foreach ($aFields as $sFieldAlias) {
|
||||||
{
|
$aMatches = [];
|
||||||
$aMatches = array();
|
if (preg_match('/^([^.]+)\\.([^.]+)$/', $sFieldAlias, $aMatches)) {
|
||||||
if (preg_match('/^([^.]+)\\.([^.]+)$/', $sFieldAlias, $aMatches))
|
|
||||||
{
|
|
||||||
$sFieldClass = $this->m_oFilter->GetClassName($aMatches[1]);
|
$sFieldClass = $this->m_oFilter->GetClassName($aMatches[1]);
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sFieldClass, $aMatches[2]);
|
$oAttDef = MetaModel::GetAttributeDef($sFieldClass, $aMatches[2]);
|
||||||
if ($oAttDef instanceof AttributeOneWayPassword)
|
if ($oAttDef instanceof AttributeOneWayPassword) {
|
||||||
{
|
|
||||||
throw new Exception('Grouping on password fields is not supported.');
|
throw new Exception('Grouping on password fields is not supported.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$aGroupBy = array();
|
$aGroupBy = [];
|
||||||
$aGroupBy['grouped_by_1'] = $oGroupByExp;
|
$aGroupBy['grouped_by_1'] = $oGroupByExp;
|
||||||
$aQueryParams = array();
|
$aQueryParams = [];
|
||||||
if (isset($aExtraParams['query_params']))
|
if (isset($aExtraParams['query_params'])) {
|
||||||
{
|
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
}
|
}
|
||||||
$aFunctions = array();
|
$aFunctions = [];
|
||||||
$sAggregationFunction = 'count';
|
$sAggregationFunction = 'count';
|
||||||
$sFctVar = '_itop_count_';
|
$sFctVar = '_itop_count_';
|
||||||
$sAggregationAttr = '';
|
$sAggregationAttr = '';
|
||||||
if (isset($aExtraParams['aggregation_function']) && !empty($aExtraParams['aggregation_attribute']))
|
if (isset($aExtraParams['aggregation_function']) && !empty($aExtraParams['aggregation_attribute'])) {
|
||||||
{
|
|
||||||
$sAggregationFunction = $aExtraParams['aggregation_function'];
|
$sAggregationFunction = $aExtraParams['aggregation_function'];
|
||||||
$sAggregationAttr = $aExtraParams['aggregation_attribute'];
|
$sAggregationAttr = $aExtraParams['aggregation_attribute'];
|
||||||
$oAttrExpr = Expression::FromOQL('`'.$sAlias.'`.`'.$sAggregationAttr.'`');
|
$oAttrExpr = Expression::FromOQL('`'.$sAlias.'`.`'.$sAggregationAttr.'`');
|
||||||
$oFctExpr = new FunctionExpression(strtoupper($sAggregationFunction), array($oAttrExpr));
|
$oFctExpr = new FunctionExpression(strtoupper($sAggregationFunction), [$oAttrExpr]);
|
||||||
$sFctVar = '_itop_'.$sAggregationFunction.'_';
|
$sFctVar = '_itop_'.$sAggregationFunction.'_';
|
||||||
$aFunctions = array($sFctVar => $oFctExpr);
|
$aFunctions = [$sFctVar => $oFctExpr];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($sAggregationAttr))
|
if (!empty($sAggregationAttr)) {
|
||||||
{
|
|
||||||
$sClass = $this->m_oFilter->GetClass();
|
$sClass = $this->m_oFilter->GetClass();
|
||||||
$sAggregationAttr = MetaModel::GetLabel($sClass, $sAggregationAttr);
|
$sAggregationAttr = MetaModel::GetLabel($sClass, $sAggregationAttr);
|
||||||
}
|
}
|
||||||
$iLimit = 0;
|
$iLimit = 0;
|
||||||
if (isset($aExtraParams['limit']))
|
if (isset($aExtraParams['limit'])) {
|
||||||
{
|
|
||||||
$iLimit = intval($aExtraParams['limit']);
|
$iLimit = intval($aExtraParams['limit']);
|
||||||
}
|
}
|
||||||
$aOrderBy = array();
|
$aOrderBy = [];
|
||||||
if (isset($aExtraParams['order_direction']) && isset($aExtraParams['order_by']))
|
if (isset($aExtraParams['order_direction']) && isset($aExtraParams['order_by'])) {
|
||||||
{
|
switch ($aExtraParams['order_by']) {
|
||||||
switch ($aExtraParams['order_by'])
|
|
||||||
{
|
|
||||||
case 'attribute':
|
case 'attribute':
|
||||||
$aOrderBy = array('grouped_by_1' => ($aExtraParams['order_direction'] === 'asc'));
|
$aOrderBy = ['grouped_by_1' => ($aExtraParams['order_direction'] === 'asc')];
|
||||||
break;
|
break;
|
||||||
case 'function':
|
case 'function':
|
||||||
$aOrderBy = array($sFctVar => ($aExtraParams['order_direction'] === 'asc'));
|
$aOrderBy = [$sFctVar => ($aExtraParams['order_direction'] === 'asc')];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1078,31 +1037,31 @@ JS
|
|||||||
$this->AddCondition($sFilterCode, $sContextParamValue);
|
$this->AddCondition($sFilterCode, $sContextParamValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aQueryParams = array();
|
$aQueryParams = [];
|
||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
}
|
}
|
||||||
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, array(), $aQueryParams);
|
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, [], $aQueryParams);
|
||||||
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Summary details
|
// Summary details
|
||||||
$aCounts = array();
|
$aCounts = [];
|
||||||
$aStateLabels = array();
|
$aStateLabels = [];
|
||||||
if (!empty($sStateAttrCode) && !empty($sStatesList)) {
|
if (!empty($sStateAttrCode) && !empty($sStatesList)) {
|
||||||
$aStates = explode(',', $sStatesList);
|
$aStates = explode(',', $sStatesList);
|
||||||
|
|
||||||
// Generate one count + group by query [#1330]
|
// Generate one count + group by query [#1330]
|
||||||
$sClassAlias = $this->m_oFilter->GetClassAlias();
|
$sClassAlias = $this->m_oFilter->GetClassAlias();
|
||||||
$oGroupByExpr = Expression::FromOQL($sClassAlias.'.'.$sStateAttrCode);
|
$oGroupByExpr = Expression::FromOQL($sClassAlias.'.'.$sStateAttrCode);
|
||||||
$aGroupBy = array('group1' => $oGroupByExpr);
|
$aGroupBy = ['group1' => $oGroupByExpr];
|
||||||
$oGroupBySearch = $this->m_oFilter->DeepClone();
|
$oGroupBySearch = $this->m_oFilter->DeepClone();
|
||||||
if (isset($this->m_bShowObsoleteData)) {
|
if (isset($this->m_bShowObsoleteData)) {
|
||||||
$oGroupBySearch->SetShowObsoleteData($this->m_bShowObsoleteData);
|
$oGroupBySearch->SetShowObsoleteData($this->m_bShowObsoleteData);
|
||||||
}
|
}
|
||||||
$sCountGroupByQuery = $oGroupBySearch->MakeGroupByQuery($aQueryParams, $aGroupBy, false);
|
$sCountGroupByQuery = $oGroupBySearch->MakeGroupByQuery($aQueryParams, $aGroupBy, false);
|
||||||
$aCountGroupByResults = CMDBSource::QueryToArray($sCountGroupByQuery);
|
$aCountGroupByResults = CMDBSource::QueryToArray($sCountGroupByQuery);
|
||||||
$aCountsQueryResults = array();
|
$aCountsQueryResults = [];
|
||||||
foreach ($aCountGroupByResults as $aCountGroupBySingleResult) {
|
foreach ($aCountGroupByResults as $aCountGroupBySingleResult) {
|
||||||
$aCountsQueryResults[$aCountGroupBySingleResult[0]] = $aCountGroupBySingleResult[1];
|
$aCountsQueryResults[$aCountGroupBySingleResult[0]] = $aCountGroupBySingleResult[1];
|
||||||
}
|
}
|
||||||
@@ -1116,7 +1075,8 @@ JS
|
|||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
if ($aCounts[$sStateValue] == 0) {
|
if ($aCounts[$sStateValue] == 0) {
|
||||||
$aCounts[$sStateValue] = ['link' => '-', 'label' => $aCounts[$sStateValue]];;
|
$aCounts[$sStateValue] = ['link' => '-', 'label' => $aCounts[$sStateValue]];
|
||||||
|
;
|
||||||
} else {
|
} else {
|
||||||
$oSingleGroupByValueFilter = $this->m_oFilter->DeepClone();
|
$oSingleGroupByValueFilter = $this->m_oFilter->DeepClone();
|
||||||
$oSingleGroupByValueFilter->AddCondition($sStateAttrCode, $sStateValue, '=');
|
$oSingleGroupByValueFilter->AddCondition($sStateAttrCode, $sStateValue, '=');
|
||||||
@@ -1166,7 +1126,7 @@ JS
|
|||||||
$oBlock->AddSubBlock($oPill);
|
$oBlock->AddSubBlock($oPill);
|
||||||
}
|
}
|
||||||
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
||||||
if(isset($aExtraParams['query_params']['this->object()'])){
|
if (isset($aExtraParams['query_params']['this->object()'])) {
|
||||||
$aExtraParams['query_params']['this->class'] = get_class($aExtraParams['query_params']['this->object()']);
|
$aExtraParams['query_params']['this->class'] = get_class($aExtraParams['query_params']['this->object()']);
|
||||||
$aExtraParams['query_params']['this->id'] = $aExtraParams['query_params']['this->object()']->GetKey();
|
$aExtraParams['query_params']['this->id'] = $aExtraParams['query_params']['this->object()']->GetKey();
|
||||||
unset($aExtraParams['query_params']['this->object()']);
|
unset($aExtraParams['query_params']['this->object()']);
|
||||||
@@ -1180,7 +1140,8 @@ JS
|
|||||||
$('#".$oBlock->GetId()."').html(data);
|
$('#".$oBlock->GetId()."').html(data);
|
||||||
$('#".$oBlock->GetId()."').unblock();
|
$('#".$oBlock->GetId()."').unblock();
|
||||||
});
|
});
|
||||||
$('#".$oBlock->GetId()."').unblock();");
|
$('#".$oBlock->GetId()."').unblock();"
|
||||||
|
);
|
||||||
|
|
||||||
return $oBlock;
|
return $oBlock;
|
||||||
}
|
}
|
||||||
@@ -1190,7 +1151,7 @@ JS
|
|||||||
*
|
*
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
protected function GetAllowedActionsParams(array $aExtraParams)
|
protected function GetAllowedActionsParams(array $aExtraParams)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'context_filter', /** int if != 0 filter with user context */
|
'context_filter', /** int if != 0 filter with user context */
|
||||||
@@ -1222,11 +1183,11 @@ JS
|
|||||||
$this->AddCondition($sFilterCode, $sContextParamValue);
|
$this->AddCondition($sFilterCode, $sContextParamValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aQueryParams = array();
|
$aQueryParams = [];
|
||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
}
|
}
|
||||||
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, array(), $aQueryParams);
|
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, [], $aQueryParams);
|
||||||
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
||||||
}
|
}
|
||||||
$iCount = $this->m_oSet->Count();
|
$iCount = $this->m_oSet->Count();
|
||||||
@@ -1243,8 +1204,15 @@ JS
|
|||||||
if (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY)) {
|
if (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY)) {
|
||||||
$sCreateActionUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=new&class='.$sClass.$oAppContext->GetForLink(true);
|
$sCreateActionUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=new&class='.$sClass.$oAppContext->GetForLink(true);
|
||||||
$sCreateActionLabel = Dict::Format('UI:Button:Create');
|
$sCreateActionLabel = Dict::Format('UI:Button:Create');
|
||||||
$oBlock = DashletFactory::MakeForDashletBadge($sClassIconUrl, $sHyperlink, $iCount, $sClassLabel, $sCreateActionUrl,
|
$oBlock = DashletFactory::MakeForDashletBadge(
|
||||||
$sCreateActionLabel, $aRefreshParams);
|
$sClassIconUrl,
|
||||||
|
$sHyperlink,
|
||||||
|
$iCount,
|
||||||
|
$sClassLabel,
|
||||||
|
$sCreateActionUrl,
|
||||||
|
$sCreateActionLabel,
|
||||||
|
$aRefreshParams
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
$oBlock = DashletFactory::MakeForDashletBadge($sClassIconUrl, $sHyperlink, $iCount, $sClassLabel, null, null, $aRefreshParams);
|
$oBlock = DashletFactory::MakeForDashletBadge($sClassIconUrl, $sHyperlink, $iCount, $sClassLabel, null, null, $aRefreshParams);
|
||||||
}
|
}
|
||||||
@@ -1274,9 +1242,9 @@ JS
|
|||||||
|
|
||||||
$aRes = CMDBSource::QueryToArray($sSql);
|
$aRes = CMDBSource::QueryToArray($sSql);
|
||||||
|
|
||||||
$aGroupBy = array();
|
$aGroupBy = [];
|
||||||
$aLabels = array();
|
$aLabels = [];
|
||||||
$aValues = array();
|
$aValues = [];
|
||||||
$iTotalCount = 0;
|
$iTotalCount = 0;
|
||||||
foreach ($aRes as $iRow => $aRow) {
|
foreach ($aRes as $iRow => $aRow) {
|
||||||
$sValue = $aRow['grouped_by_1'];
|
$sValue = $aRow['grouped_by_1'];
|
||||||
@@ -1287,7 +1255,7 @@ JS
|
|||||||
$iTotalCount += $aRow['_itop_count_'];
|
$iTotalCount += $aRow['_itop_count_'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$aData = array();
|
$aData = [];
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sParams = $oAppContext->GetForLink(true);
|
$sParams = $oAppContext->GetForLink(true);
|
||||||
foreach ($aGroupBy as $iRow => $iCount) {
|
foreach ($aGroupBy as $iRow => $iCount) {
|
||||||
@@ -1298,22 +1266,22 @@ JS
|
|||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
} else {
|
} else {
|
||||||
$aQueryParams = array();
|
$aQueryParams = [];
|
||||||
}
|
}
|
||||||
$sFilter = rawurlencode($oSubsetSearch->serialize(false, $aQueryParams));
|
$sFilter = rawurlencode($oSubsetSearch->serialize(false, $aQueryParams));
|
||||||
|
|
||||||
$aData[] = array(
|
$aData[] = [
|
||||||
'group' => $aLabels[$iRow],
|
'group' => $aLabels[$iRow],
|
||||||
'value' => "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&dosearch=1$sParams&filter=$sFilter\">$iCount</a>"
|
'value' => "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&dosearch=1$sParams&filter=$sFilter\">$iCount</a>",
|
||||||
); // TO DO: add the context information
|
]; // TO DO: add the context information
|
||||||
}
|
}
|
||||||
$aAttribs = array(
|
$aAttribs = [
|
||||||
'group' => array('label' => $sGroupByLabel, 'description' => ''),
|
'group' => ['label' => $sGroupByLabel, 'description' => ''],
|
||||||
'value' => array(
|
'value' => [
|
||||||
'label' => Dict::S('UI:GroupBy:'.$sAggregationFunction),
|
'label' => Dict::S('UI:GroupBy:'.$sAggregationFunction),
|
||||||
'description' => Dict::Format('UI:GroupBy:'.$sAggregationFunction.'+', $sAggregationAttr),
|
'description' => Dict::Format('UI:GroupBy:'.$sAggregationFunction.'+', $sAggregationAttr),
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
$sFormat = isset($aExtraParams['format']) ? $aExtraParams['format'] : 'UI:Pagination:HeaderNoSelection';
|
$sFormat = isset($aExtraParams['format']) ? $aExtraParams['format'] : 'UI:Pagination:HeaderNoSelection';
|
||||||
|
|
||||||
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
||||||
@@ -1324,7 +1292,7 @@ JS
|
|||||||
$oBlock = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
|
$oBlock = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
|
||||||
$oBlock->AddSubTitleBlock(new Html($sTitle));
|
$oBlock->AddSubTitleBlock(new Html($sTitle));
|
||||||
$oBlock->AddCSSClass('ibo-datatable-panel');
|
$oBlock->AddCSSClass('ibo-datatable-panel');
|
||||||
if(isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0){
|
if (isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0) {
|
||||||
$oBlock->SetIcon($aExtraParams["panel_icon"]);
|
$oBlock->SetIcon($aExtraParams["panel_icon"]);
|
||||||
}
|
}
|
||||||
$oDataTable = DataTableUIBlockFactory::MakeForStaticData("", $aAttribs, $aData, null, $aExtraParams, $this->m_oFilter->ToOQL(), $aOption);
|
$oDataTable = DataTableUIBlockFactory::MakeForStaticData("", $aAttribs, $aData, null, $aExtraParams, $this->m_oFilter->ToOQL(), $aOption);
|
||||||
@@ -1343,7 +1311,7 @@ JS
|
|||||||
}
|
}
|
||||||
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
|
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
|
||||||
$oBlock = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
|
$oBlock = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
|
||||||
if(isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0){
|
if (isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0) {
|
||||||
$oBlock->SetIcon($aExtraParams["panel_icon"]);
|
$oBlock->SetIcon($aExtraParams["panel_icon"]);
|
||||||
}
|
}
|
||||||
$oBlock->AddSubBlock(new Html('<p>'.Dict::Format($sFormat, $iCount).'</p>'));
|
$oBlock->AddSubBlock(new Html('<p>'.Dict::Format($sFormat, $iCount).'</p>'));
|
||||||
@@ -1353,7 +1321,7 @@ JS
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $oBlock;
|
return $oBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param WebPage $oPage
|
* @param WebPage $oPage
|
||||||
@@ -1411,7 +1379,6 @@ JS
|
|||||||
$oBlock->aExtraParams = $aExtraParams;
|
$oBlock->aExtraParams = $aExtraParams;
|
||||||
$oBlock->sFilter = $this->m_oFilter->ToOQL();
|
$oBlock->sFilter = $this->m_oFilter->ToOQL();
|
||||||
|
|
||||||
|
|
||||||
// Check the classes that can be read (i.e authorized) by this user...
|
// Check the classes that can be read (i.e authorized) by this user...
|
||||||
foreach ($aClasses as $sAlias => $sClassName) {
|
foreach ($aClasses as $sAlias => $sClassName) {
|
||||||
if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $this->m_oSet) != UR_ALLOWED_NO) {
|
if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $this->m_oSet) != UR_ALLOWED_NO) {
|
||||||
@@ -1433,7 +1400,7 @@ JS
|
|||||||
$sSearchFilter = $this->m_oSet->GetFilter()->serialize();
|
$sSearchFilter = $this->m_oSet->GetFilter()->serialize();
|
||||||
// Limit the size of the URL (N°1585 - request uri too long)
|
// Limit the size of the URL (N°1585 - request uri too long)
|
||||||
if (strlen($sSearchFilter) < SERVER_MAX_URL_LENGTH) {
|
if (strlen($sSearchFilter) < SERVER_MAX_URL_LENGTH) {
|
||||||
$oBlock->sEventAttachedData = json_encode(array(
|
$oBlock->sEventAttachedData = json_encode([
|
||||||
'filter' => $sSearchFilter,
|
'filter' => $sSearchFilter,
|
||||||
'breadcrumb_id' => "ui-search-".$this->m_oSet->GetClass(),
|
'breadcrumb_id' => "ui-search-".$this->m_oSet->GetClass(),
|
||||||
'breadcrumb_label' => MetaModel::GetName($this->m_oSet->GetClass()),
|
'breadcrumb_label' => MetaModel::GetName($this->m_oSet->GetClass()),
|
||||||
@@ -1441,7 +1408,7 @@ JS
|
|||||||
'breadcrumb_instance_id' => MetaModel::GetConfig()->GetItopInstanceid(),
|
'breadcrumb_instance_id' => MetaModel::GetConfig()->GetItopInstanceid(),
|
||||||
'breadcrumb_icon' => 'fas fa-search',
|
'breadcrumb_icon' => 'fas fa-search',
|
||||||
'breadcrumb_icon_type' => iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES,
|
'breadcrumb_icon_type' => iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES,
|
||||||
));
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1474,25 +1441,25 @@ JS
|
|||||||
$oContentBlock = new UIContentBlock();
|
$oContentBlock = new UIContentBlock();
|
||||||
$oHtml = new Html();
|
$oHtml = new Html();
|
||||||
$oContentBlock->AddSubBlock($oHtml);
|
$oContentBlock->AddSubBlock($oHtml);
|
||||||
$aDisplayAliases = isset($aExtraParams['display_aliases']) ? explode(',', $aExtraParams['display_aliases']) : array();
|
$aDisplayAliases = isset($aExtraParams['display_aliases']) ? explode(',', $aExtraParams['display_aliases']) : [];
|
||||||
if (!isset($aExtraParams['group_by'])) {
|
if (!isset($aExtraParams['group_by'])) {
|
||||||
$oHtml->AddHtml('<p>'.Dict::S('UI:Error:MandatoryTemplateParameter_group_by').'</p>');
|
$oHtml->AddHtml('<p>'.Dict::S('UI:Error:MandatoryTemplateParameter_group_by').'</p>');
|
||||||
} else {
|
} else {
|
||||||
$aGroupByFields = array();
|
$aGroupByFields = [];
|
||||||
$aGroupBy = explode(',', $aExtraParams['group_by']);
|
$aGroupBy = explode(',', $aExtraParams['group_by']);
|
||||||
foreach ($aGroupBy as $sGroupBy) {
|
foreach ($aGroupBy as $sGroupBy) {
|
||||||
$aMatches = array();
|
$aMatches = [];
|
||||||
if (preg_match('/^(.+)\.(.+)$/', $sGroupBy, $aMatches) > 0) {
|
if (preg_match('/^(.+)\.(.+)$/', $sGroupBy, $aMatches) > 0) {
|
||||||
$aGroupByFields[] = array('alias' => $aMatches[1], 'att_code' => $aMatches[2]);
|
$aGroupByFields[] = ['alias' => $aMatches[1], 'att_code' => $aMatches[2]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count($aGroupByFields) == 0) {
|
if (count($aGroupByFields) == 0) {
|
||||||
$oHtml->AddHtml('<p>'.Dict::Format('UI:Error:InvalidGroupByFields', $aExtraParams['group_by']).'</p>');
|
$oHtml->AddHtml('<p>'.Dict::Format('UI:Error:InvalidGroupByFields', $aExtraParams['group_by']).'</p>');
|
||||||
} else {
|
} else {
|
||||||
$aResults = array();
|
$aResults = [];
|
||||||
$aCriteria = array();
|
$aCriteria = [];
|
||||||
while ($aObjects = $this->m_oSet->FetchAssoc()) {
|
while ($aObjects = $this->m_oSet->FetchAssoc()) {
|
||||||
$aKeys = array();
|
$aKeys = [];
|
||||||
foreach ($aGroupByFields as $aField) {
|
foreach ($aGroupByFields as $aField) {
|
||||||
$sAlias = $aField['alias'];
|
$sAlias = $aField['alias'];
|
||||||
if (is_null($aObjects[$sAlias])) {
|
if (is_null($aObjects[$sAlias])) {
|
||||||
@@ -1509,7 +1476,7 @@ JS
|
|||||||
$oHtml->AddHtml("<table>\n");
|
$oHtml->AddHtml("<table>\n");
|
||||||
// Construct a new (parametric) query that will return the content of this block
|
// Construct a new (parametric) query that will return the content of this block
|
||||||
$oBlockFilter = $this->m_oFilter->DeepClone();
|
$oBlockFilter = $this->m_oFilter->DeepClone();
|
||||||
$aExpressions = array();
|
$aExpressions = [];
|
||||||
$index = 0;
|
$index = 0;
|
||||||
foreach ($aGroupByFields as $aField) {
|
foreach ($aGroupByFields as $aField) {
|
||||||
$aExpressions[] = '`'.$aField['alias'].'`.`'.$aField['att_code'].'` = :param'.$index++;
|
$aExpressions[] = '`'.$aField['alias'].'`.`'.$aField['att_code'].'` = :param'.$index++;
|
||||||
@@ -1521,7 +1488,7 @@ JS
|
|||||||
foreach ($aResults as $sCategory => $aObjects) {
|
foreach ($aResults as $sCategory => $aObjects) {
|
||||||
$oHtml->AddHtml("<tr><td><h1>$sCategory</h1></td></tr>\n");
|
$oHtml->AddHtml("<tr><td><h1>$sCategory</h1></td></tr>\n");
|
||||||
if (count($aDisplayAliases) == 1) {
|
if (count($aDisplayAliases) == 1) {
|
||||||
$aSimpleArray = array();
|
$aSimpleArray = [];
|
||||||
foreach ($aObjects as $aRow) {
|
foreach ($aObjects as $aRow) {
|
||||||
$oObj = $aRow[$aDisplayAliases[0]];
|
$oObj = $aRow[$aDisplayAliases[0]];
|
||||||
if (!is_null($oObj)) {
|
if (!is_null($oObj)) {
|
||||||
@@ -1537,12 +1504,12 @@ JS
|
|||||||
$oHtml->AddHtml("</td></tr>\n");
|
$oHtml->AddHtml("</td></tr>\n");
|
||||||
} else {
|
} else {
|
||||||
$index = 0;
|
$index = 0;
|
||||||
$aArgs = array();
|
$aArgs = [];
|
||||||
foreach ($aGroupByFields as $aField) {
|
foreach ($aGroupByFields as $aField) {
|
||||||
$aArgs['param'.$index] = $aCriteria[$sCategory][$aField['alias'].'.'.$aField['att_code']];
|
$aArgs['param'.$index] = $aCriteria[$sCategory][$aField['alias'].'.'.$aField['att_code']];
|
||||||
$index++;
|
$index++;
|
||||||
}
|
}
|
||||||
$oSet = new CMDBObjectSet($oBlockFilter, array(), $aArgs);
|
$oSet = new CMDBObjectSet($oBlockFilter, [], $aArgs);
|
||||||
if (empty($aExtraParams['currentId'])) {
|
if (empty($aExtraParams['currentId'])) {
|
||||||
$iListId = utils::GetUniqueId(); // Works only if not in an Ajax page !!
|
$iListId = utils::GetUniqueId(); // Works only if not in an Ajax page !!
|
||||||
} else {
|
} else {
|
||||||
@@ -1603,8 +1570,10 @@ JS
|
|||||||
$sDefaults .= '&'.urlencode($sName).'='.urlencode($sValue);
|
$sDefaults .= '&'.urlencode($sName).'='.urlencode($sValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$oBlock->AddHtml("<p><a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=modify_links&class=$sClass&sParams&link_attr=".$aExtraParams['link_attr']."&id=".$aExtraParams['object_id']."&target_class=$sTargetClass&addObjects=true$sDefaults\">".Dict::Format('UI:ClickToCreateNew',
|
$oBlock->AddHtml("<p><a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=modify_links&class=$sClass&sParams&link_attr=".$aExtraParams['link_attr']."&id=".$aExtraParams['object_id']."&target_class=$sTargetClass&addObjects=true$sDefaults\">".Dict::Format(
|
||||||
Metamodel::GetName($sClass))."</a></p>\n");
|
'UI:ClickToCreateNew',
|
||||||
|
Metamodel::GetName($sClass)
|
||||||
|
)."</a></p>\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1653,7 +1622,7 @@ JS
|
|||||||
|
|
||||||
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
|
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
|
||||||
$oPanel = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
|
$oPanel = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
|
||||||
if(isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0){
|
if (isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0) {
|
||||||
$oPanel->SetIcon($aExtraParams["panel_icon"]);
|
$oPanel->SetIcon($aExtraParams["panel_icon"]);
|
||||||
}
|
}
|
||||||
$oPanel->AddSubBlock($oBlock);
|
$oPanel->AddSubBlock($oBlock);
|
||||||
@@ -1677,7 +1646,7 @@ JS
|
|||||||
{
|
{
|
||||||
$sChartType = isset($aExtraParams['chart_type']) ? $aExtraParams['chart_type'] : 'pie';
|
$sChartType = isset($aExtraParams['chart_type']) ? $aExtraParams['chart_type'] : 'pie';
|
||||||
$sId = utils::ReadParam('id', '');
|
$sId = utils::ReadParam('id', '');
|
||||||
$aValues = array();
|
$aValues = [];
|
||||||
$oBlock = null;
|
$oBlock = null;
|
||||||
$sJSURLs = '';
|
$sJSURLs = '';
|
||||||
|
|
||||||
@@ -1688,21 +1657,18 @@ JS
|
|||||||
$this->MakeGroupByQuery($aExtraParams, $oGroupByExp, $sGroupByLabel, $aGroupBy, $sAggregationFunction, $sFctVar, $sAggregationAttr, $sSql);
|
$this->MakeGroupByQuery($aExtraParams, $oGroupByExp, $sGroupByLabel, $aGroupBy, $sAggregationFunction, $sFctVar, $sAggregationAttr, $sSql);
|
||||||
$aRes = CMDBSource::QueryToArray($sSql);
|
$aRes = CMDBSource::QueryToArray($sSql);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$iTotalCount = 0;
|
$iTotalCount = 0;
|
||||||
$aURLs = array();
|
$aURLs = [];
|
||||||
|
|
||||||
foreach ($aRes as $iRow => $aRow) {
|
foreach ($aRes as $iRow => $aRow) {
|
||||||
$sValue = $aRow['grouped_by_1'];
|
$sValue = $aRow['grouped_by_1'];
|
||||||
$sHtmlValue = $oGroupByExp->MakeValueLabel($this->m_oFilter, $sValue, $sValue);
|
$sHtmlValue = $oGroupByExp->MakeValueLabel($this->m_oFilter, $sValue, $sValue);
|
||||||
$iTotalCount += $aRow['_itop_count_'];
|
$iTotalCount += $aRow['_itop_count_'];
|
||||||
$aValues[] = array(
|
$aValues[] = [
|
||||||
'label' => html_entity_decode(strip_tags($sHtmlValue), ENT_QUOTES, 'UTF-8'),
|
'label' => html_entity_decode(strip_tags($sHtmlValue), ENT_QUOTES, 'UTF-8'),
|
||||||
'label_html' => $sHtmlValue,
|
'label_html' => $sHtmlValue,
|
||||||
'value' => (float)$aRow[$sFctVar],
|
'value' => (float)$aRow[$sFctVar],
|
||||||
);
|
];
|
||||||
|
|
||||||
|
|
||||||
// Build the search for this subset
|
// Build the search for this subset
|
||||||
$oSubsetSearch = $this->m_oFilter->DeepClone();
|
$oSubsetSearch = $this->m_oFilter->DeepClone();
|
||||||
@@ -1741,7 +1707,7 @@ JS
|
|||||||
$aColumns = [];
|
$aColumns = [];
|
||||||
$aNames = [];
|
$aNames = [];
|
||||||
foreach ($aValues as $idx => $aValue) {
|
foreach ($aValues as $idx => $aValue) {
|
||||||
$aColumns[] = array('series_'.$idx, (float)$aValue['value']);
|
$aColumns[] = ['series_'.$idx, (float)$aValue['value']];
|
||||||
$aNames['series_'.$idx] = $aValue['label'];
|
$aNames['series_'.$idx] = $aValue['label'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1763,7 +1729,7 @@ JS
|
|||||||
}
|
}
|
||||||
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
|
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
|
||||||
$oPanel = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
|
$oPanel = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
|
||||||
if(isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0){
|
if (isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0) {
|
||||||
$oPanel->SetIcon($aExtraParams["panel_icon"]);
|
$oPanel->SetIcon($aExtraParams["panel_icon"]);
|
||||||
}
|
}
|
||||||
$oPanel->AddSubBlock($oBlock);
|
$oPanel->AddSubBlock($oBlock);
|
||||||
@@ -1790,12 +1756,12 @@ JS
|
|||||||
$oBlock->sDownloadLink = utils::GetAbsoluteUrlAppRoot().'webservices/export.php?expression='.urlencode($this->m_oFilter->ToOQL(true)).'&format=csv&filename='.urlencode($oBlock->sCsvFile);
|
$oBlock->sDownloadLink = utils::GetAbsoluteUrlAppRoot().'webservices/export.php?expression='.urlencode($this->m_oFilter->ToOQL(true)).'&format=csv&filename='.urlencode($oBlock->sCsvFile);
|
||||||
$oBlock->sLinkToToggle = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search'.$oAppContext->GetForLink(true).'&filter='.rawurlencode($this->m_oFilter->serialize()).'&format=csv';
|
$oBlock->sLinkToToggle = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search'.$oAppContext->GetForLink(true).'&filter='.rawurlencode($this->m_oFilter->serialize()).'&format=csv';
|
||||||
// Pass the parameters via POST, since expression may be very long
|
// Pass the parameters via POST, since expression may be very long
|
||||||
$aParamsToPost = array(
|
$aParamsToPost = [
|
||||||
'expression' => $this->m_oFilter->ToOQL(true),
|
'expression' => $this->m_oFilter->ToOQL(true),
|
||||||
'format' => 'csv',
|
'format' => 'csv',
|
||||||
'filename' => $oBlock->sCsvFile,
|
'filename' => $oBlock->sCsvFile,
|
||||||
'charset' => 'UTF-8',
|
'charset' => 'UTF-8',
|
||||||
);
|
];
|
||||||
if ($oBlock->bAdvancedMode) {
|
if ($oBlock->bAdvancedMode) {
|
||||||
$oBlock->sDownloadLink .= '&fields_advanced=1';
|
$oBlock->sDownloadLink .= '&fields_advanced=1';
|
||||||
$aParamsToPost['fields_advanced'] = 1;
|
$aParamsToPost['fields_advanced'] = 1;
|
||||||
@@ -1854,8 +1820,7 @@ class MenuBlock extends DisplayBlock
|
|||||||
$oRouter = Router::GetInstance();
|
$oRouter = Router::GetInstance();
|
||||||
$oRenderBlock = new UIContentBlock();
|
$oRenderBlock = new UIContentBlock();
|
||||||
|
|
||||||
if ($this->m_sStyle == 'popup') // popup is a synonym of 'list' for backward compatibility
|
if ($this->m_sStyle == 'popup') { // popup is a synonym of 'list' for backward compatibility
|
||||||
{
|
|
||||||
$this->m_sStyle = static::ENUM_STYLE_LIST;
|
$this->m_sStyle = static::ENUM_STYLE_LIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1890,7 +1855,6 @@ class MenuBlock extends DisplayBlock
|
|||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sContext = $oAppContext->GetForLink(true);
|
$sContext = $oAppContext->GetForLink(true);
|
||||||
|
|
||||||
|
|
||||||
$sFilter = $this->GetFilter()->serialize();
|
$sFilter = $this->GetFilter()->serialize();
|
||||||
$sUIPage = cmdbAbstractObject::ComputeStandardUIPage($sClass);
|
$sUIPage = cmdbAbstractObject::ComputeStandardUIPage($sClass);
|
||||||
$sRootUrl = utils::GetAbsoluteUrlAppRoot();
|
$sRootUrl = utils::GetAbsoluteUrlAppRoot();
|
||||||
@@ -1948,7 +1912,7 @@ class MenuBlock extends DisplayBlock
|
|||||||
$iLimit = MetaModel::GetConfig()->Get('complex_actions_limit');
|
$iLimit = MetaModel::GetConfig()->Get('complex_actions_limit');
|
||||||
if (
|
if (
|
||||||
($iSetCount > 0) && (false === $bLocked) && MetaModel::HasLifecycle($sClass) &&
|
($iSetCount > 0) && (false === $bLocked) && MetaModel::HasLifecycle($sClass) &&
|
||||||
( ($iLimit == 0) || ($iSetCount < $iLimit) )
|
(($iLimit == 0) || ($iSetCount < $iLimit))
|
||||||
) {
|
) {
|
||||||
$aTransitions = [];
|
$aTransitions = [];
|
||||||
// Processing (optimizations) and endpoints are not exactly the same depending on if there is only 1 object or a set
|
// Processing (optimizations) and endpoints are not exactly the same depending on if there is only 1 object or a set
|
||||||
@@ -1968,8 +1932,8 @@ class MenuBlock extends DisplayBlock
|
|||||||
// Life cycle actions may be available... if all objects are in the same state
|
// Life cycle actions may be available... if all objects are in the same state
|
||||||
// Group by <state>
|
// Group by <state>
|
||||||
$oGroupByExp = new FieldExpression(MetaModel::GetStateAttributeCode($sClass), $this->m_oFilter->GetClassAlias());
|
$oGroupByExp = new FieldExpression(MetaModel::GetStateAttributeCode($sClass), $this->m_oFilter->GetClassAlias());
|
||||||
$aGroupBy = array('__state__' => $oGroupByExp);
|
$aGroupBy = ['__state__' => $oGroupByExp];
|
||||||
$aQueryParams = array();
|
$aQueryParams = [];
|
||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
}
|
}
|
||||||
@@ -2001,10 +1965,10 @@ class MenuBlock extends DisplayBlock
|
|||||||
switch ($iActionAllowed) {
|
switch ($iActionAllowed) {
|
||||||
case UR_ALLOWED_YES:
|
case UR_ALLOWED_YES:
|
||||||
case UR_ALLOWED_DEPENDS:
|
case UR_ALLOWED_DEPENDS:
|
||||||
$aTransitionActions[$sStimulusCode] = array(
|
$aTransitionActions[$sStimulusCode] = [
|
||||||
'label' => $aStimuli[$sStimulusCode]->GetLabel(),
|
'label' => $aStimuli[$sStimulusCode]->GetLabel(),
|
||||||
'url' => "{$sRootUrl}pages/UI.php?stimulus=$sStimulusCode&class=$sLifecycleClass&{$sUrlQueryString}",
|
'url' => "{$sRootUrl}pages/UI.php?stimulus=$sStimulusCode&class=$sLifecycleClass&{$sUrlQueryString}",
|
||||||
) + $aActionParams;
|
] + $aActionParams;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -2066,16 +2030,16 @@ class MenuBlock extends DisplayBlock
|
|||||||
// Just one object in the set, possible actions are "new / clone / modify and delete"
|
// Just one object in the set, possible actions are "new / clone / modify and delete"
|
||||||
if (!isset($aExtraParams['link_attr'])) {
|
if (!isset($aExtraParams['link_attr'])) {
|
||||||
if ($bIsModifyAllowed) {
|
if ($bIsModifyAllowed) {
|
||||||
$aRegularActions['UI:Menu:Modify'] = array(
|
$aRegularActions['UI:Menu:Modify'] = [
|
||||||
'label' => Dict::S('UI:Menu:Modify'),
|
'label' => Dict::S('UI:Menu:Modify'),
|
||||||
'url' => $oRouter->GenerateUrl('object.modify', ['class' => $sClass, 'id' => $id]) . "{$sContext}#",
|
'url' => $oRouter->GenerateUrl('object.modify', ['class' => $sClass, 'id' => $id])."{$sContext}#",
|
||||||
) + $aActionParams;
|
] + $aActionParams;
|
||||||
}
|
}
|
||||||
if ($bIsDeleteAllowed) {
|
if ($bIsDeleteAllowed) {
|
||||||
$aRegularActions['UI:Menu:Delete'] = array(
|
$aRegularActions['UI:Menu:Delete'] = [
|
||||||
'label' => Dict::S('UI:Menu:Delete'),
|
'label' => Dict::S('UI:Menu:Delete'),
|
||||||
'url' => "{$sRootUrl}pages/$sUIPage?operation=delete&class=$sClass&id=$id{$sContext}",
|
'url' => "{$sRootUrl}pages/$sUIPage?operation=delete&class=$sClass&id=$id{$sContext}",
|
||||||
) + $aActionParams;
|
] + $aActionParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relations...
|
// Relations...
|
||||||
@@ -2084,16 +2048,16 @@ class MenuBlock extends DisplayBlock
|
|||||||
$this->AddMenuSeparator($aRegularActions);
|
$this->AddMenuSeparator($aRegularActions);
|
||||||
foreach ($aRelations as $sRelationCode => $aRelationInfo) {
|
foreach ($aRelations as $sRelationCode => $aRelationInfo) {
|
||||||
if (array_key_exists('down', $aRelationInfo)) {
|
if (array_key_exists('down', $aRelationInfo)) {
|
||||||
$aRegularActions[$sRelationCode.'_down'] = array(
|
$aRegularActions[$sRelationCode.'_down'] = [
|
||||||
'label' => $aRelationInfo['down'],
|
'label' => $aRelationInfo['down'],
|
||||||
'url' => "{$sRootUrl}pages/$sUIPage?operation=view_relations&relation=$sRelationCode&direction=down&class=$sClass&id=$id{$sContext}",
|
'url' => "{$sRootUrl}pages/$sUIPage?operation=view_relations&relation=$sRelationCode&direction=down&class=$sClass&id=$id{$sContext}",
|
||||||
) + $aActionParams;
|
] + $aActionParams;
|
||||||
}
|
}
|
||||||
if (array_key_exists('up', $aRelationInfo)) {
|
if (array_key_exists('up', $aRelationInfo)) {
|
||||||
$aRegularActions[$sRelationCode.'_up'] = array(
|
$aRegularActions[$sRelationCode.'_up'] = [
|
||||||
'label' => $aRelationInfo['up'],
|
'label' => $aRelationInfo['up'],
|
||||||
'url' => "{$sRootUrl}pages/$sUIPage?operation=view_relations&relation=$sRelationCode&direction=up&class=$sClass&id=$id{$sContext}",
|
'url' => "{$sRootUrl}pages/$sUIPage?operation=view_relations&relation=$sRelationCode&direction=up&class=$sClass&id=$id{$sContext}",
|
||||||
) + $aActionParams;
|
] + $aActionParams;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2105,7 +2069,7 @@ class MenuBlock extends DisplayBlock
|
|||||||
$bCanKill = false;
|
$bCanKill = false;
|
||||||
|
|
||||||
$oUser = UserRights::GetUserObject();
|
$oUser = UserRights::GetUserObject();
|
||||||
$aUserProfiles = array();
|
$aUserProfiles = [];
|
||||||
if (!is_null($oUser)) {
|
if (!is_null($oUser)) {
|
||||||
$oProfileSet = $oUser->Get('profile_list');
|
$oProfileSet = $oUser->Get('profile_list');
|
||||||
while ($oProfile = $oProfileSet->Fetch()) {
|
while ($oProfile = $oProfileSet->Fetch()) {
|
||||||
@@ -2127,10 +2091,10 @@ class MenuBlock extends DisplayBlock
|
|||||||
|
|
||||||
if ($bCanKill) {
|
if ($bCanKill) {
|
||||||
$this->AddMenuSeparator($aRegularActions);
|
$this->AddMenuSeparator($aRegularActions);
|
||||||
$aRegularActions['concurrent_lock_unlock'] = array(
|
$aRegularActions['concurrent_lock_unlock'] = [
|
||||||
'label' => Dict::S('UI:Menu:KillConcurrentLock'),
|
'label' => Dict::S('UI:Menu:KillConcurrentLock'),
|
||||||
'url' => "{$sRootUrl}pages/$sUIPage?operation=kill_lock&class=$sClass&id=$id{$sContext}",
|
'url' => "{$sRootUrl}pages/$sUIPage?operation=kill_lock&class=$sClass&id=$id{$sContext}",
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2138,7 +2102,7 @@ class MenuBlock extends DisplayBlock
|
|||||||
$this->AddMenuSeparator($aRegularActions);
|
$this->AddMenuSeparator($aRegularActions);
|
||||||
|
|
||||||
$this->GetEnumAllowedActions($oSet, function ($sLabel, $data) use (&$aRegularActions, $aActionParams) {
|
$this->GetEnumAllowedActions($oSet, function ($sLabel, $data) use (&$aRegularActions, $aActionParams) {
|
||||||
$aRegularActions[$sLabel] = array('label' => $sLabel, 'url' => $data) + $aActionParams;
|
$aRegularActions[$sLabel] = ['label' => $sLabel, 'url' => $data] + $aActionParams;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2474,13 +2438,11 @@ class MenuBlock extends DisplayBlock
|
|||||||
protected function AddMenuSeparator(&$aActions)
|
protected function AddMenuSeparator(&$aActions)
|
||||||
{
|
{
|
||||||
$sSeparator = '<hr class="menu-separator"/>';
|
$sSeparator = '<hr class="menu-separator"/>';
|
||||||
if (count($aActions) > 0) // Make sure that the separator is not the first item in the menu
|
if (count($aActions) > 0) { // Make sure that the separator is not the first item in the menu
|
||||||
{
|
|
||||||
$aKeys = array_keys($aActions);
|
$aKeys = array_keys($aActions);
|
||||||
$sLastKey = array_pop($aKeys);
|
$sLastKey = array_pop($aKeys);
|
||||||
if ($aActions[$sLastKey]['label'] != $sSeparator) // Make sure there are no 2 consecutive separators
|
if ($aActions[$sLastKey]['label'] != $sSeparator) { // Make sure there are no 2 consecutive separators
|
||||||
{
|
$aActions['sep_'.(count($aActions) - 1)] = ['label' => $sSeparator, 'url' => ''];
|
||||||
$aActions['sep_'.(count($aActions)-1)] = array('label' => $sSeparator, 'url' => '');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2540,10 +2502,10 @@ class MenuBlock extends DisplayBlock
|
|||||||
*/
|
*/
|
||||||
protected function AddBulkDeleteObjectsMenuAction(array &$aActions, string $sClass, string $sFilter, string $sActionIdentifier = 'UI:Menu:BulkDelete', $sActionLabel = 'UI:Menu:BulkDelete')
|
protected function AddBulkDeleteObjectsMenuAction(array &$aActions, string $sClass, string $sFilter, string $sActionIdentifier = 'UI:Menu:BulkDelete', $sActionLabel = 'UI:Menu:BulkDelete')
|
||||||
{
|
{
|
||||||
$aActions[$sActionIdentifier] = array(
|
$aActions[$sActionIdentifier] = [
|
||||||
'label' => Dict::S($sActionLabel),
|
'label' => Dict::S($sActionLabel),
|
||||||
'url' => $this->PrepareUrlForStandardMenuAction($sClass, "operation=select_for_deletion&filter=".urlencode($sFilter)),
|
'url' => $this->PrepareUrlForStandardMenuAction($sClass, "operation=select_for_deletion&filter=".urlencode($sFilter)),
|
||||||
) + $this->GetDefaultParamsForMenuAction();
|
] + $this->GetDefaultParamsForMenuAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2580,6 +2542,6 @@ class MenuBlock extends DisplayBlock
|
|||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sContext = $oAppContext->GetForLink(true);
|
$sContext = $oAppContext->GetForLink(true);
|
||||||
|
|
||||||
return $sUrl . $sContext;
|
return $sUrl.$sContext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader');
|
||||||
|
|||||||
@@ -19,73 +19,67 @@ class ExcelExporter
|
|||||||
protected $iPosition;
|
protected $iPosition;
|
||||||
protected $sOutputFilePath;
|
protected $sOutputFilePath;
|
||||||
protected $bAdvancedMode;
|
protected $bAdvancedMode;
|
||||||
|
|
||||||
public function __construct($sToken = null)
|
public function __construct($sToken = null)
|
||||||
{
|
{
|
||||||
$this->aStatistics = array(
|
$this->aStatistics = [
|
||||||
'objects_count' => 0,
|
'objects_count' => 0,
|
||||||
'total_duration' => 0,
|
'total_duration' => 0,
|
||||||
'data_retrieval_duration' => 0,
|
'data_retrieval_duration' => 0,
|
||||||
'excel_build_duration' => 0,
|
'excel_build_duration' => 0,
|
||||||
'excel_write_duration' => 0,
|
'excel_write_duration' => 0,
|
||||||
'peak_memory_usage' => 0,
|
'peak_memory_usage' => 0,
|
||||||
);
|
];
|
||||||
$this->fStartTime = microtime(true);
|
$this->fStartTime = microtime(true);
|
||||||
$this->oSearch = null;
|
$this->oSearch = null;
|
||||||
|
|
||||||
$this->sState = 'new';
|
$this->sState = 'new';
|
||||||
$this->aObjectsIDs = array();
|
$this->aObjectsIDs = [];
|
||||||
$this->iPosition = 0;
|
$this->iPosition = 0;
|
||||||
$this->aAuthorizedClasses = null;
|
$this->aAuthorizedClasses = null;
|
||||||
$this->aTableHeaders = null;
|
$this->aTableHeaders = null;
|
||||||
$this->sOutputFilePath = null;
|
$this->sOutputFilePath = null;
|
||||||
$this->bAdvancedMode = false;
|
$this->bAdvancedMode = false;
|
||||||
$this->CheckDataDir();
|
$this->CheckDataDir();
|
||||||
if ($sToken == null)
|
if ($sToken == null) {
|
||||||
{
|
|
||||||
$this->sToken = $this->GetNewToken();
|
$this->sToken = $this->GetNewToken();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->sToken = $sToken;
|
$this->sToken = $sToken;
|
||||||
$this->ReloadState();
|
$this->ReloadState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __destruct()
|
public function __destruct()
|
||||||
{
|
{
|
||||||
if (($this->sState != 'done') && ($this->sState != 'error') && ($this->sToken != null))
|
if (($this->sState != 'done') && ($this->sState != 'error') && ($this->sToken != null)) {
|
||||||
{
|
|
||||||
// Operation in progress, save the state
|
// Operation in progress, save the state
|
||||||
$this->SaveState();
|
$this->SaveState();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Operation completed, cleanup the temp files
|
// Operation completed, cleanup the temp files
|
||||||
@unlink($this->GetStateFile());
|
@unlink($this->GetStateFile());
|
||||||
@unlink($this->GetDataFile());
|
@unlink($this->GetDataFile());
|
||||||
}
|
}
|
||||||
self::CleanupOldFiles();
|
self::CleanupOldFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SetChunkSize($iChunkSize)
|
public function SetChunkSize($iChunkSize)
|
||||||
{
|
{
|
||||||
$this->iChunkSize = $iChunkSize;
|
$this->iChunkSize = $iChunkSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SetOutputFilePath($sDestFilePath)
|
public function SetOutputFilePath($sDestFilePath)
|
||||||
{
|
{
|
||||||
$this->sOutputFilePath = $sDestFilePath;
|
$this->sOutputFilePath = $sDestFilePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SetAdvancedMode($bAdvanced)
|
public function SetAdvancedMode($bAdvanced)
|
||||||
{
|
{
|
||||||
$this->bAdvancedMode = $bAdvanced;
|
$this->bAdvancedMode = $bAdvanced;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SaveState()
|
public function SaveState()
|
||||||
{
|
{
|
||||||
$aState = array(
|
$aState = [
|
||||||
'state' => $this->sState,
|
'state' => $this->sState,
|
||||||
'statistics' => $this->aStatistics,
|
'statistics' => $this->aStatistics,
|
||||||
'filter' => $this->oSearch->serialize(),
|
'filter' => $this->oSearch->serialize(),
|
||||||
@@ -94,31 +88,28 @@ class ExcelExporter
|
|||||||
'object_ids' => $this->aObjectsIDs,
|
'object_ids' => $this->aObjectsIDs,
|
||||||
'output_file_path' => $this->sOutputFilePath,
|
'output_file_path' => $this->sOutputFilePath,
|
||||||
'advanced_mode' => $this->bAdvancedMode,
|
'advanced_mode' => $this->bAdvancedMode,
|
||||||
);
|
];
|
||||||
|
|
||||||
file_put_contents($this->GetStateFile(), json_encode($aState));
|
file_put_contents($this->GetStateFile(), json_encode($aState));
|
||||||
|
|
||||||
return $this->sToken;
|
return $this->sToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ReloadState()
|
public function ReloadState()
|
||||||
{
|
{
|
||||||
if ($this->sToken == null)
|
if ($this->sToken == null) {
|
||||||
{
|
|
||||||
throw new Exception('ExcelExporter not initialized with a token, cannot reload state');
|
throw new Exception('ExcelExporter not initialized with a token, cannot reload state');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file_exists($this->GetStateFile()))
|
if (!file_exists($this->GetStateFile())) {
|
||||||
{
|
|
||||||
throw new Exception("ExcelExporter: missing status file '".$this->GetStateFile()."', cannot reload state.");
|
throw new Exception("ExcelExporter: missing status file '".$this->GetStateFile()."', cannot reload state.");
|
||||||
}
|
}
|
||||||
$sJson = file_get_contents($this->GetStateFile());
|
$sJson = file_get_contents($this->GetStateFile());
|
||||||
$aState = json_decode($sJson, true);
|
$aState = json_decode($sJson, true);
|
||||||
if ($aState === null)
|
if ($aState === null) {
|
||||||
{
|
|
||||||
throw new Exception("ExcelExporter:corrupted status file '".$this->GetStateFile()."', not a JSON, cannot reload state.");
|
throw new Exception("ExcelExporter:corrupted status file '".$this->GetStateFile()."', not a JSON, cannot reload state.");
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->sState = $aState['state'];
|
$this->sState = $aState['state'];
|
||||||
$this->aStatistics = $aState['statistics'];
|
$this->aStatistics = $aState['statistics'];
|
||||||
$this->oSearch = DBObjectSearch::unserialize($aState['filter']);
|
$this->oSearch = DBObjectSearch::unserialize($aState['filter']);
|
||||||
@@ -128,206 +119,183 @@ class ExcelExporter
|
|||||||
$this->sOutputFilePath = $aState['output_file_path'];
|
$this->sOutputFilePath = $aState['output_file_path'];
|
||||||
$this->bAdvancedMode = $aState['advanced_mode'];
|
$this->bAdvancedMode = $aState['advanced_mode'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SetObjectList($oSearch)
|
public function SetObjectList($oSearch)
|
||||||
{
|
{
|
||||||
$this->oSearch = $oSearch;
|
$this->oSearch = $oSearch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Run()
|
public function Run()
|
||||||
{
|
{
|
||||||
$sCode = 'error';
|
$sCode = 'error';
|
||||||
$iPercentage = 100;
|
$iPercentage = 100;
|
||||||
$sMessage = Dict::Format('ExcelExporter:ErrorUnexpected_State', $this->sState);
|
$sMessage = Dict::Format('ExcelExporter:ErrorUnexpected_State', $this->sState);
|
||||||
$fTime = microtime(true);
|
$fTime = microtime(true);
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
switch ($this->sState) {
|
||||||
switch($this->sState)
|
|
||||||
{
|
|
||||||
case 'new':
|
case 'new':
|
||||||
$oIDSet = new DBObjectSet($this->oSearch);
|
$oIDSet = new DBObjectSet($this->oSearch);
|
||||||
$oIDSet->OptimizeColumnLoad(array('id'));
|
$oIDSet->OptimizeColumnLoad(['id']);
|
||||||
$this->aObjectsIDs = array();
|
$this->aObjectsIDs = [];
|
||||||
while($oObj = $oIDSet->Fetch())
|
while ($oObj = $oIDSet->Fetch()) {
|
||||||
{
|
$this->aObjectsIDs[] = $oObj->GetKey();
|
||||||
$this->aObjectsIDs[] = $oObj->GetKey();
|
|
||||||
}
|
|
||||||
$sCode = 'retrieving-data';
|
|
||||||
$iPercentage = 5;
|
|
||||||
$sMessage = Dict::S('ExcelExporter:RetrievingData');
|
|
||||||
$this->iPosition = 0;
|
|
||||||
$this->aStatistics['objects_count'] = count($this->aObjectsIDs);
|
|
||||||
$this->aStatistics['data_retrieval_duration'] += microtime(true) - $fTime;
|
|
||||||
|
|
||||||
// The first line of the file is the "headers" specifying the label and the type of each column
|
|
||||||
$this->GetFieldsList($oIDSet, $this->bAdvancedMode);
|
|
||||||
$sRow = json_encode($this->aTableHeaders);
|
|
||||||
$hFile = @fopen($this->GetDataFile(), 'ab');
|
|
||||||
if ($hFile === false)
|
|
||||||
{
|
|
||||||
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for writing.');
|
|
||||||
}
|
|
||||||
fwrite($hFile, $sRow."\n");
|
|
||||||
fclose($hFile);
|
|
||||||
|
|
||||||
// Next state
|
|
||||||
$this->sState = 'retrieving-data';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'retrieving-data':
|
|
||||||
$oCurrentSearch = clone $this->oSearch;
|
|
||||||
$aIDs = array_slice($this->aObjectsIDs, $this->iPosition, $this->iChunkSize);
|
|
||||||
|
|
||||||
$oCurrentSearch->AddCondition('id', $aIDs, 'IN');
|
|
||||||
$hFile = @fopen($this->GetDataFile(), 'ab');
|
|
||||||
if ($hFile === false)
|
|
||||||
{
|
|
||||||
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for writing.');
|
|
||||||
}
|
|
||||||
$oSet = new DBObjectSet($oCurrentSearch);
|
|
||||||
$this->GetFieldsList($oSet, $this->bAdvancedMode);
|
|
||||||
while($aObjects = $oSet->FetchAssoc())
|
|
||||||
{
|
|
||||||
$aRow = array();
|
|
||||||
foreach($this->aAuthorizedClasses as $sAlias => $sClassName)
|
|
||||||
{
|
|
||||||
$oObj = $aObjects[$sAlias];
|
|
||||||
if ($this->bAdvancedMode)
|
|
||||||
{
|
|
||||||
$aRow[] = $oObj->GetKey();
|
|
||||||
}
|
|
||||||
foreach($this->aFieldsList[$sAlias] as $sAttCodeEx => $oAttDef)
|
|
||||||
{
|
|
||||||
$value = $oObj->Get($sAttCodeEx);
|
|
||||||
if ($value instanceOf ormCaseLog)
|
|
||||||
{
|
|
||||||
// Extract the case log as text and remove the "===" which make Excel think that the cell contains a formula the next time you edit it!
|
|
||||||
$sExcelVal = trim(preg_replace('/========== ([^=]+) ============/', '********** $1 ************', $value->GetText()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$sExcelVal = $oAttDef->GetEditValue($value, $oObj);
|
|
||||||
}
|
|
||||||
$aRow[] = $sExcelVal;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$sRow = json_encode($aRow);
|
|
||||||
fwrite($hFile, $sRow."\n");
|
|
||||||
}
|
|
||||||
fclose($hFile);
|
|
||||||
|
|
||||||
if (($this->iPosition + $this->iChunkSize) > count($this->aObjectsIDs))
|
|
||||||
{
|
|
||||||
// Next state
|
|
||||||
$this->sState = 'building-excel';
|
|
||||||
$sCode = 'building-excel';
|
|
||||||
$iPercentage = 80;
|
|
||||||
$sMessage = Dict::S('ExcelExporter:BuildingExcelFile');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$sCode = 'retrieving-data';
|
$sCode = 'retrieving-data';
|
||||||
$this->iPosition += $this->iChunkSize;
|
$iPercentage = 5;
|
||||||
$iPercentage = 5 + round(75 * ($this->iPosition / count($this->aObjectsIDs)));
|
$sMessage = Dict::S('ExcelExporter:RetrievingData');
|
||||||
$sMessage = Dict::S('ExcelExporter:RetrievingData');
|
$this->iPosition = 0;
|
||||||
}
|
$this->aStatistics['objects_count'] = count($this->aObjectsIDs);
|
||||||
break;
|
$this->aStatistics['data_retrieval_duration'] += microtime(true) - $fTime;
|
||||||
|
|
||||||
|
// The first line of the file is the "headers" specifying the label and the type of each column
|
||||||
|
$this->GetFieldsList($oIDSet, $this->bAdvancedMode);
|
||||||
|
$sRow = json_encode($this->aTableHeaders);
|
||||||
|
$hFile = @fopen($this->GetDataFile(), 'ab');
|
||||||
|
if ($hFile === false) {
|
||||||
|
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for writing.');
|
||||||
|
}
|
||||||
|
fwrite($hFile, $sRow."\n");
|
||||||
|
fclose($hFile);
|
||||||
|
|
||||||
|
// Next state
|
||||||
|
$this->sState = 'retrieving-data';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'retrieving-data':
|
||||||
|
$oCurrentSearch = clone $this->oSearch;
|
||||||
|
$aIDs = array_slice($this->aObjectsIDs, $this->iPosition, $this->iChunkSize);
|
||||||
|
|
||||||
|
$oCurrentSearch->AddCondition('id', $aIDs, 'IN');
|
||||||
|
$hFile = @fopen($this->GetDataFile(), 'ab');
|
||||||
|
if ($hFile === false) {
|
||||||
|
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for writing.');
|
||||||
|
}
|
||||||
|
$oSet = new DBObjectSet($oCurrentSearch);
|
||||||
|
$this->GetFieldsList($oSet, $this->bAdvancedMode);
|
||||||
|
while ($aObjects = $oSet->FetchAssoc()) {
|
||||||
|
$aRow = [];
|
||||||
|
foreach ($this->aAuthorizedClasses as $sAlias => $sClassName) {
|
||||||
|
$oObj = $aObjects[$sAlias];
|
||||||
|
if ($this->bAdvancedMode) {
|
||||||
|
$aRow[] = $oObj->GetKey();
|
||||||
|
}
|
||||||
|
foreach ($this->aFieldsList[$sAlias] as $sAttCodeEx => $oAttDef) {
|
||||||
|
$value = $oObj->Get($sAttCodeEx);
|
||||||
|
if ($value instanceof ormCaseLog) {
|
||||||
|
// Extract the case log as text and remove the "===" which make Excel think that the cell contains a formula the next time you edit it!
|
||||||
|
$sExcelVal = trim(preg_replace('/========== ([^=]+) ============/', '********** $1 ************', $value->GetText()));
|
||||||
|
} else {
|
||||||
|
$sExcelVal = $oAttDef->GetEditValue($value, $oObj);
|
||||||
|
}
|
||||||
|
$aRow[] = $sExcelVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sRow = json_encode($aRow);
|
||||||
|
fwrite($hFile, $sRow."\n");
|
||||||
|
}
|
||||||
|
fclose($hFile);
|
||||||
|
|
||||||
|
if (($this->iPosition + $this->iChunkSize) > count($this->aObjectsIDs)) {
|
||||||
|
// Next state
|
||||||
|
$this->sState = 'building-excel';
|
||||||
|
$sCode = 'building-excel';
|
||||||
|
$iPercentage = 80;
|
||||||
|
$sMessage = Dict::S('ExcelExporter:BuildingExcelFile');
|
||||||
|
} else {
|
||||||
|
$sCode = 'retrieving-data';
|
||||||
|
$this->iPosition += $this->iChunkSize;
|
||||||
|
$iPercentage = 5 + round(75 * ($this->iPosition / count($this->aObjectsIDs)));
|
||||||
|
$sMessage = Dict::S('ExcelExporter:RetrievingData');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 'building-excel':
|
case 'building-excel':
|
||||||
$hFile = @fopen($this->GetDataFile(), 'rb');
|
$hFile = @fopen($this->GetDataFile(), 'rb');
|
||||||
if ($hFile === false)
|
if ($hFile === false) {
|
||||||
{
|
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for reading.');
|
||||||
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for reading.');
|
}
|
||||||
}
|
$sHeaders = fgets($hFile);
|
||||||
$sHeaders = fgets($hFile);
|
$aHeaders = json_decode($sHeaders, true);
|
||||||
$aHeaders = json_decode($sHeaders, true);
|
|
||||||
|
$aData = [];
|
||||||
$aData = array();
|
while ($sLine = fgets($hFile)) {
|
||||||
while($sLine = fgets($hFile))
|
$aRow = json_decode($sLine);
|
||||||
{
|
$aData[] = $aRow;
|
||||||
$aRow = json_decode($sLine);
|
}
|
||||||
$aData[] = $aRow;
|
fclose($hFile);
|
||||||
}
|
@unlink($this->GetDataFile());
|
||||||
fclose($hFile);
|
|
||||||
@unlink($this->GetDataFile());
|
$fStartExcel = microtime(true);
|
||||||
|
$writer = new XLSXWriter();
|
||||||
$fStartExcel = microtime(true);
|
$writer->setAuthor(UserRights::GetUserFriendlyName());
|
||||||
$writer = new XLSXWriter();
|
$writer->writeSheet($aData, 'Sheet1', $aHeaders);
|
||||||
$writer->setAuthor(UserRights::GetUserFriendlyName());
|
$fExcelTime = microtime(true) - $fStartExcel;
|
||||||
$writer->writeSheet($aData,'Sheet1', $aHeaders);
|
$this->aStatistics['excel_build_duration'] = $fExcelTime;
|
||||||
$fExcelTime = microtime(true) - $fStartExcel;
|
|
||||||
$this->aStatistics['excel_build_duration'] = $fExcelTime;
|
$fTime = microtime(true);
|
||||||
|
$writer->writeToFile($this->GetExcelFilePath());
|
||||||
$fTime = microtime(true);
|
$fExcelSaveTime = microtime(true) - $fTime;
|
||||||
$writer->writeToFile($this->GetExcelFilePath());
|
$this->aStatistics['excel_write_duration'] = $fExcelSaveTime;
|
||||||
$fExcelSaveTime = microtime(true) - $fTime;
|
|
||||||
$this->aStatistics['excel_write_duration'] = $fExcelSaveTime;
|
// Next state
|
||||||
|
$this->sState = 'done';
|
||||||
// Next state
|
$sCode = 'done';
|
||||||
$this->sState = 'done';
|
$iPercentage = 100;
|
||||||
$sCode = 'done';
|
$sMessage = Dict::S('ExcelExporter:Done');
|
||||||
$iPercentage = 100;
|
break;
|
||||||
$sMessage = Dict::S('ExcelExporter:Done');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'done':
|
case 'done':
|
||||||
$this->sState = 'done';
|
$this->sState = 'done';
|
||||||
$sCode = 'done';
|
$sCode = 'done';
|
||||||
$iPercentage = 100;
|
$iPercentage = 100;
|
||||||
$sMessage = Dict::S('ExcelExporter:Done');
|
$sMessage = Dict::S('ExcelExporter:Done');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch(Exception $e)
|
|
||||||
{
|
|
||||||
$sCode = 'error';
|
$sCode = 'error';
|
||||||
$sMessage = $e->getMessage();
|
$sMessage = $e->getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->aStatistics['total_duration'] += microtime(true) - $fTime;
|
$this->aStatistics['total_duration'] += microtime(true) - $fTime;
|
||||||
$peak_memory = memory_get_peak_usage(true);
|
$peak_memory = memory_get_peak_usage(true);
|
||||||
if ($peak_memory > $this->aStatistics['peak_memory_usage'])
|
if ($peak_memory > $this->aStatistics['peak_memory_usage']) {
|
||||||
{
|
|
||||||
$this->aStatistics['peak_memory_usage'] = $peak_memory;
|
$this->aStatistics['peak_memory_usage'] = $peak_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
return [
|
||||||
'code' => $sCode,
|
'code' => $sCode,
|
||||||
'message' => $sMessage,
|
'message' => $sMessage,
|
||||||
'percentage' => $iPercentage,
|
'percentage' => $iPercentage,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetExcelFilePath()
|
public function GetExcelFilePath()
|
||||||
{
|
{
|
||||||
if ($this->sOutputFilePath == null)
|
if ($this->sOutputFilePath == null) {
|
||||||
{
|
|
||||||
return APPROOT.'data/bulk_export/'.$this->sToken.'.xlsx';
|
return APPROOT.'data/bulk_export/'.$this->sToken.'.xlsx';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return $this->sOutputFilePath;
|
return $this->sOutputFilePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function GetExcelFileFromToken($sToken)
|
public static function GetExcelFileFromToken($sToken)
|
||||||
{
|
{
|
||||||
return @file_get_contents(APPROOT.'data/bulk_export/'.$sToken.'.xlsx');
|
return @file_get_contents(APPROOT.'data/bulk_export/'.$sToken.'.xlsx');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function CleanupFromToken($sToken)
|
public static function CleanupFromToken($sToken)
|
||||||
{
|
{
|
||||||
@unlink(APPROOT.'data/bulk_export/'.$sToken.'.status');
|
@unlink(APPROOT.'data/bulk_export/'.$sToken.'.status');
|
||||||
@unlink(APPROOT.'data/bulk_export/'.$sToken.'.data');
|
@unlink(APPROOT.'data/bulk_export/'.$sToken.'.data');
|
||||||
@unlink(APPROOT.'data/bulk_export/'.$sToken.'.xlsx');
|
@unlink(APPROOT.'data/bulk_export/'.$sToken.'.xlsx');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Cleanup()
|
public function Cleanup()
|
||||||
{
|
{
|
||||||
self::CleanupFromToken($this->sToken);
|
self::CleanupFromToken($this->sToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete all files in the data/bulk_export directory which are older than 1 day
|
* Delete all files in the data/bulk_export directory which are older than 1 day
|
||||||
* unless a different delay is configured.
|
* unless a different delay is configured.
|
||||||
@@ -336,15 +304,12 @@ class ExcelExporter
|
|||||||
{
|
{
|
||||||
$aFiles = glob(APPROOT.'data/bulk_export/*.*');
|
$aFiles = glob(APPROOT.'data/bulk_export/*.*');
|
||||||
$iDelay = MetaModel::GetConfig()->Get('xlsx_exporter_cleanup_old_files_delay');
|
$iDelay = MetaModel::GetConfig()->Get('xlsx_exporter_cleanup_old_files_delay');
|
||||||
|
|
||||||
if($iDelay > 0)
|
if ($iDelay > 0) {
|
||||||
{
|
foreach ($aFiles as $sFile) {
|
||||||
foreach($aFiles as $sFile)
|
|
||||||
{
|
|
||||||
$iModificationTime = filemtime($sFile);
|
$iModificationTime = filemtime($sFile);
|
||||||
|
|
||||||
if($iModificationTime < (time() - $iDelay))
|
if ($iModificationTime < (time() - $iDelay)) {
|
||||||
{
|
|
||||||
// Temporary files older than one day are deleted
|
// Temporary files older than one day are deleted
|
||||||
//echo "Supposed to delete: '".$sFile." (Unix Modification Time: $iModificationTime)'\n";
|
//echo "Supposed to delete: '".$sFile." (Unix Modification Time: $iModificationTime)'\n";
|
||||||
@unlink($sFile);
|
@unlink($sFile);
|
||||||
@@ -352,189 +317,155 @@ class ExcelExporter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function DisplayStatistics(Page $oPage)
|
public function DisplayStatistics(Page $oPage)
|
||||||
{
|
{
|
||||||
$aStats = array(
|
$aStats = [
|
||||||
'Number of objects exported' => $this->aStatistics['objects_count'],
|
'Number of objects exported' => $this->aStatistics['objects_count'],
|
||||||
'Total export duration' => sprintf('%.3f s', $this->aStatistics['total_duration']),
|
'Total export duration' => sprintf('%.3f s', $this->aStatistics['total_duration']),
|
||||||
'Data retrieval duration' => sprintf('%.3f s', $this->aStatistics['data_retrieval_duration']),
|
'Data retrieval duration' => sprintf('%.3f s', $this->aStatistics['data_retrieval_duration']),
|
||||||
'Excel build duration' => sprintf('%.3f s', $this->aStatistics['excel_build_duration']),
|
'Excel build duration' => sprintf('%.3f s', $this->aStatistics['excel_build_duration']),
|
||||||
'Excel write duration' => sprintf('%.3f s', $this->aStatistics['excel_write_duration']),
|
'Excel write duration' => sprintf('%.3f s', $this->aStatistics['excel_write_duration']),
|
||||||
'Peak memory usage' => self::HumanDisplay($this->aStatistics['peak_memory_usage']),
|
'Peak memory usage' => self::HumanDisplay($this->aStatistics['peak_memory_usage']),
|
||||||
);
|
];
|
||||||
|
|
||||||
if ($oPage instanceof CLIPage)
|
if ($oPage instanceof CLIPage) {
|
||||||
{
|
|
||||||
$oPage->add($this->GetStatistics('text'));
|
$oPage->add($this->GetStatistics('text'));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oPage->add($this->GetStatistics('html'));
|
$oPage->add($this->GetStatistics('html'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetStatistics($sFormat = 'html')
|
public function GetStatistics($sFormat = 'html')
|
||||||
{
|
{
|
||||||
$sStats = '';
|
$sStats = '';
|
||||||
$aStats = array(
|
$aStats = [
|
||||||
'Number of objects exported' => $this->aStatistics['objects_count'],
|
'Number of objects exported' => $this->aStatistics['objects_count'],
|
||||||
'Total export duration' => sprintf('%.3f s', $this->aStatistics['total_duration']),
|
'Total export duration' => sprintf('%.3f s', $this->aStatistics['total_duration']),
|
||||||
'Data retrieval duration' => sprintf('%.3f s', $this->aStatistics['data_retrieval_duration']),
|
'Data retrieval duration' => sprintf('%.3f s', $this->aStatistics['data_retrieval_duration']),
|
||||||
'Excel build duration' => sprintf('%.3f s', $this->aStatistics['excel_build_duration']),
|
'Excel build duration' => sprintf('%.3f s', $this->aStatistics['excel_build_duration']),
|
||||||
'Excel write duration' => sprintf('%.3f s', $this->aStatistics['excel_write_duration']),
|
'Excel write duration' => sprintf('%.3f s', $this->aStatistics['excel_write_duration']),
|
||||||
'Peak memory usage' => self::HumanDisplay($this->aStatistics['peak_memory_usage']),
|
'Peak memory usage' => self::HumanDisplay($this->aStatistics['peak_memory_usage']),
|
||||||
);
|
];
|
||||||
|
|
||||||
if ($sFormat == 'text')
|
if ($sFormat == 'text') {
|
||||||
{
|
foreach ($aStats as $sLabel => $sValue) {
|
||||||
foreach($aStats as $sLabel => $sValue)
|
|
||||||
{
|
|
||||||
$sStats .= "+------------------------------+----------+\n";
|
$sStats .= "+------------------------------+----------+\n";
|
||||||
$sStats .= sprintf("|%-30s|%10s|\n", $sLabel, $sValue);
|
$sStats .= sprintf("|%-30s|%10s|\n", $sLabel, $sValue);
|
||||||
}
|
}
|
||||||
$sStats .= "+------------------------------+----------+";
|
$sStats .= "+------------------------------+----------+";
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sStats .= '<table><tbody>';
|
$sStats .= '<table><tbody>';
|
||||||
foreach($aStats as $sLabel => $sValue)
|
foreach ($aStats as $sLabel => $sValue) {
|
||||||
{
|
|
||||||
$sStats .= "<tr><td>$sLabel</td><td>$sValue</td></tr>";
|
$sStats .= "<tr><td>$sLabel</td><td>$sValue</td></tr>";
|
||||||
}
|
}
|
||||||
$sStats .= '</tbody></table>';
|
$sStats .= '</tbody></table>';
|
||||||
|
|
||||||
}
|
}
|
||||||
return $sStats;
|
return $sStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function HumanDisplay($iSize)
|
public static function HumanDisplay($iSize)
|
||||||
{
|
{
|
||||||
$aUnits = array('B','KB','MB','GB','TB','PB');
|
$aUnits = ['B','KB','MB','GB','TB','PB'];
|
||||||
return @round($iSize/pow(1024,($i=floor(log($iSize,1024)))),2).' '.$aUnits[$i];
|
return @round($iSize / pow(1024, ($i = floor(log($iSize, 1024)))), 2).' '.$aUnits[$i];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function CheckDataDir()
|
protected function CheckDataDir()
|
||||||
{
|
{
|
||||||
if(!is_dir(APPROOT."data/bulk_export"))
|
if (!is_dir(APPROOT."data/bulk_export")) {
|
||||||
{
|
|
||||||
@mkdir(APPROOT."data/bulk_export", 0777, true /* recursive */);
|
@mkdir(APPROOT."data/bulk_export", 0777, true /* recursive */);
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
}
|
}
|
||||||
if (!is_writable(APPROOT."data/bulk_export"))
|
if (!is_writable(APPROOT."data/bulk_export")) {
|
||||||
{
|
|
||||||
throw new Exception('Data directory "'.APPROOT.'data/bulk_export" could not be written.');
|
throw new Exception('Data directory "'.APPROOT.'data/bulk_export" could not be written.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function GetStateFile($sToken = null)
|
protected function GetStateFile($sToken = null)
|
||||||
{
|
{
|
||||||
if ($sToken == null)
|
if ($sToken == null) {
|
||||||
{
|
|
||||||
$sToken = $this->sToken;
|
$sToken = $this->sToken;
|
||||||
}
|
}
|
||||||
return APPROOT."data/bulk_export/$sToken.status";
|
return APPROOT."data/bulk_export/$sToken.status";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function GetDataFile()
|
protected function GetDataFile()
|
||||||
{
|
{
|
||||||
return APPROOT.'data/bulk_export/'.$this->sToken.'.data';
|
return APPROOT.'data/bulk_export/'.$this->sToken.'.data';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function GetNewToken()
|
protected function GetNewToken()
|
||||||
{
|
{
|
||||||
$iNum = rand();
|
$iNum = rand();
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
$iNum++;
|
$iNum++;
|
||||||
$sToken = sprintf("%08x", $iNum);
|
$sToken = sprintf("%08x", $iNum);
|
||||||
$sFileName = $this->GetStateFile($sToken);
|
$sFileName = $this->GetStateFile($sToken);
|
||||||
$hFile = @fopen($sFileName, 'x');
|
$hFile = @fopen($sFileName, 'x');
|
||||||
}
|
} while ($hFile === false);
|
||||||
while($hFile === false);
|
|
||||||
|
|
||||||
fclose($hFile);
|
fclose($hFile);
|
||||||
return $sToken;
|
return $sToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function GetFieldsList($oSet, $bFieldsAdvanced = false, $bLocalize = true, $aFields = null)
|
protected function GetFieldsList($oSet, $bFieldsAdvanced = false, $bLocalize = true, $aFields = null)
|
||||||
{
|
{
|
||||||
$this->aFieldsList = array();
|
$this->aFieldsList = [];
|
||||||
|
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$aClasses = $oSet->GetFilter()->GetSelectedClasses();
|
$aClasses = $oSet->GetFilter()->GetSelectedClasses();
|
||||||
$this->aAuthorizedClasses = array();
|
$this->aAuthorizedClasses = [];
|
||||||
foreach($aClasses as $sAlias => $sClassName)
|
foreach ($aClasses as $sAlias => $sClassName) {
|
||||||
{
|
if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $oSet) != UR_ALLOWED_NO) {
|
||||||
if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $oSet) != UR_ALLOWED_NO)
|
|
||||||
{
|
|
||||||
$this->aAuthorizedClasses[$sAlias] = $sClassName;
|
$this->aAuthorizedClasses[$sAlias] = $sClassName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aAttribs = array();
|
$aAttribs = [];
|
||||||
$this->aTableHeaders = array();
|
$this->aTableHeaders = [];
|
||||||
foreach($this->aAuthorizedClasses as $sAlias => $sClassName)
|
foreach ($this->aAuthorizedClasses as $sAlias => $sClassName) {
|
||||||
{
|
$aList[$sAlias] = [];
|
||||||
$aList[$sAlias] = array();
|
|
||||||
|
foreach (MetaModel::ListAttributeDefs($sClassName) as $sAttCode => $oAttDef) {
|
||||||
foreach(MetaModel::ListAttributeDefs($sClassName) as $sAttCode => $oAttDef)
|
if (is_null($aFields) || (count($aFields) == 0)) {
|
||||||
{
|
|
||||||
if (is_null($aFields) || (count($aFields) == 0))
|
|
||||||
{
|
|
||||||
// Standard list of attributes (no link sets)
|
// Standard list of attributes (no link sets)
|
||||||
if ($oAttDef->IsScalar() && ($oAttDef->IsWritable() || $oAttDef->IsExternalField()))
|
if ($oAttDef->IsScalar() && ($oAttDef->IsWritable() || $oAttDef->IsExternalField())) {
|
||||||
{
|
|
||||||
$sAttCodeEx = $oAttDef->IsExternalField() ? $oAttDef->GetKeyAttCode().'->'.$oAttDef->GetExtAttCode() : $sAttCode;
|
$sAttCodeEx = $oAttDef->IsExternalField() ? $oAttDef->GetKeyAttCode().'->'.$oAttDef->GetExtAttCode() : $sAttCode;
|
||||||
|
|
||||||
if ($oAttDef->IsExternalKey(EXTKEY_ABSOLUTE))
|
if ($oAttDef->IsExternalKey(EXTKEY_ABSOLUTE)) {
|
||||||
{
|
if ($bFieldsAdvanced) {
|
||||||
if ($bFieldsAdvanced)
|
|
||||||
{
|
|
||||||
$aList[$sAlias][$sAttCodeEx] = $oAttDef;
|
$aList[$sAlias][$sAttCodeEx] = $oAttDef;
|
||||||
|
|
||||||
if ($oAttDef->IsExternalKey(EXTKEY_RELATIVE))
|
if ($oAttDef->IsExternalKey(EXTKEY_RELATIVE)) {
|
||||||
{
|
$sRemoteClass = $oAttDef->GetTargetClass();
|
||||||
$sRemoteClass = $oAttDef->GetTargetClass();
|
foreach (MetaModel::GetReconcKeys($sRemoteClass) as $sRemoteAttCode) {
|
||||||
foreach(MetaModel::GetReconcKeys($sRemoteClass) as $sRemoteAttCode)
|
|
||||||
{
|
|
||||||
$this->aFieldsList[$sAlias][$sAttCode.'->'.$sRemoteAttCode] = MetaModel::GetAttributeDef($sRemoteClass, $sRemoteAttCode);
|
$this->aFieldsList[$sAlias][$sAttCode.'->'.$sRemoteAttCode] = MetaModel::GetAttributeDef($sRemoteClass, $sRemoteAttCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Any other attribute
|
// Any other attribute
|
||||||
$this->aFieldsList[$sAlias][$sAttCodeEx] = $oAttDef;
|
$this->aFieldsList[$sAlias][$sAttCodeEx] = $oAttDef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// User defined list of attributes
|
// User defined list of attributes
|
||||||
if (in_array($sAttCode, $aFields) || in_array($sAlias.'.'.$sAttCode, $aFields))
|
if (in_array($sAttCode, $aFields) || in_array($sAlias.'.'.$sAttCode, $aFields)) {
|
||||||
{
|
|
||||||
$this->aFieldsList[$sAlias][$sAttCode] = $oAttDef;
|
$this->aFieldsList[$sAlias][$sAttCode] = $oAttDef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($bFieldsAdvanced)
|
if ($bFieldsAdvanced) {
|
||||||
{
|
|
||||||
$this->aTableHeaders['id'] = '0';
|
$this->aTableHeaders['id'] = '0';
|
||||||
}
|
}
|
||||||
foreach($this->aFieldsList[$sAlias] as $sAttCodeEx => $oAttDef)
|
foreach ($this->aFieldsList[$sAlias] as $sAttCodeEx => $oAttDef) {
|
||||||
{
|
|
||||||
$sLabel = $bLocalize ? MetaModel::GetLabel($sClassName, $sAttCodeEx, isset($aParams['showMandatoryFields'])) : $sAttCodeEx;
|
$sLabel = $bLocalize ? MetaModel::GetLabel($sClassName, $sAttCodeEx, isset($aParams['showMandatoryFields'])) : $sAttCodeEx;
|
||||||
if($oAttDef instanceof AttributeDateTime)
|
if ($oAttDef instanceof AttributeDateTime) {
|
||||||
{
|
|
||||||
$this->aTableHeaders[$sLabel] = 'datetime';
|
$this->aTableHeaders[$sLabel] = 'datetime';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->aTableHeaders[$sLabel] = 'string';
|
$this->aTableHeaders[$sLabel] = 'string';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -6,4 +7,4 @@
|
|||||||
|
|
||||||
class BulkChangeException extends CoreException
|
class BulkChangeException extends CoreException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -6,4 +7,4 @@
|
|||||||
|
|
||||||
class CSVParserException extends CoreException
|
class CSVParserException extends CoreException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -6,4 +7,4 @@
|
|||||||
|
|
||||||
class ConfigException extends CoreException
|
class ConfigException extends CoreException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -63,21 +64,20 @@ class CoreCannotSaveObjectException extends CoreException
|
|||||||
public function getTextMessage()
|
public function getTextMessage()
|
||||||
{
|
{
|
||||||
$sTitle = Dict::S('UI:Error:SaveFailed');
|
$sTitle = Dict::S('UI:Error:SaveFailed');
|
||||||
$sContent = $sTitle;
|
$sContent = $sTitle;
|
||||||
|
|
||||||
if (count($this->aIssues) == 1) {
|
if (count($this->aIssues) == 1) {
|
||||||
$sIssue = reset($this->aIssues);
|
$sIssue = reset($this->aIssues);
|
||||||
$sContent .= $sIssue;
|
$sContent .= $sIssue;
|
||||||
} else {
|
} else {
|
||||||
foreach ($this->aIssues as $sError) {
|
foreach ($this->aIssues as $sError) {
|
||||||
$sContent .= " " . $sError . ", ";
|
$sContent .= " ".$sError.", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sContent;
|
return $sContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getIssues()
|
public function getIssues()
|
||||||
{
|
{
|
||||||
return $this->aIssues;
|
return $this->aIssues;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -35,10 +36,10 @@ class CoreException extends Exception
|
|||||||
}
|
}
|
||||||
if (count($this->m_aContextData) > 0) {
|
if (count($this->m_aContextData) > 0) {
|
||||||
$sMessage .= ": ";
|
$sMessage .= ": ";
|
||||||
$aContextItems = array();
|
$aContextItems = [];
|
||||||
foreach ($this->m_aContextData as $sKey => $value) {
|
foreach ($this->m_aContextData as $sKey => $value) {
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
$aPairs = array();
|
$aPairs = [];
|
||||||
foreach ($value as $key => $val) {
|
foreach ($value as $key => $val) {
|
||||||
if (is_array($val)) {
|
if (is_array($val)) {
|
||||||
$aPairs[] = $key.'=>('.implode(', ', $val).')';
|
$aPairs[] = $key.'=>('.implode(', ', $val).')';
|
||||||
@@ -109,4 +110,4 @@ class CoreException extends Exception
|
|||||||
{
|
{
|
||||||
return $this->m_aContextData;
|
return $this->m_aContextData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -9,5 +10,4 @@
|
|||||||
*/
|
*/
|
||||||
class CorePortalInvalidActionRuleException extends CoreException
|
class CorePortalInvalidActionRuleException extends CoreException
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -14,4 +15,4 @@ class CoreTemplateException extends CoreException
|
|||||||
$sMessage = "Twig Exception when rendering '$sTemplatePath' : ".$oTwigException->getMessage();
|
$sMessage = "Twig Exception when rendering '$sTemplatePath' : ".$oTwigException->getMessage();
|
||||||
parent::__construct($sMessage, null, '', $oTwigException);
|
parent::__construct($sMessage, null, '', $oTwigException);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -6,4 +7,4 @@
|
|||||||
|
|
||||||
class DeleteException extends CoreException
|
class DeleteException extends CoreException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ class InvalidExternalKeyValueException extends CoreUnexpectedValue
|
|||||||
|
|
||||||
public function __construct($oObject, $sAttCode, $aContextData = null, $oPrevious = null)
|
public function __construct($oObject, $sAttCode, $aContextData = null, $oPrevious = null)
|
||||||
{
|
{
|
||||||
$aContextData[self::ENUM_PARAMS_OBJECT] = get_class($oObject) . '::' . $oObject->GetKey();
|
$aContextData[self::ENUM_PARAMS_OBJECT] = get_class($oObject).'::'.$oObject->GetKey();
|
||||||
$aContextData[self::ENUM_PARAMS_ATTCODE] = $sAttCode;
|
$aContextData[self::ENUM_PARAMS_ATTCODE] = $sAttCode;
|
||||||
$aContextData[self::ENUM_PARAMS_ATTVALUE] = $oObject->Get($sAttCode);
|
$aContextData[self::ENUM_PARAMS_ATTVALUE] = $oObject->Get($sAttCode);
|
||||||
|
|
||||||
$oCurrentUser = UserRights::GetUserObject();
|
$oCurrentUser = UserRights::GetUserObject();
|
||||||
if (false === is_null($oCurrentUser)) {
|
if (false === is_null($oCurrentUser)) {
|
||||||
$aContextData[self::ENUM_PARAMS_USER] = get_class($oCurrentUser) . '::' . $oCurrentUser->GetKey();
|
$aContextData[self::ENUM_PARAMS_USER] = get_class($oCurrentUser).'::'.$oCurrentUser->GetKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct('Attribute pointing to an object that is either non existing or not readable by the current user', $aContextData, '', $oPrevious);
|
parent::__construct('Attribute pointing to an object that is either non existing or not readable by the current user', $aContextData, '', $oPrevious);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -11,4 +12,4 @@
|
|||||||
*/
|
*/
|
||||||
class InvalidPasswordAttributeOneWayPassword extends CoreException
|
class InvalidPasswordAttributeOneWayPassword extends CoreException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -10,4 +11,4 @@ use Exception;
|
|||||||
|
|
||||||
class PageNotFoundException extends Exception
|
class PageNotFoundException extends Exception
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -6,4 +7,4 @@
|
|||||||
|
|
||||||
class SynchroExceptionNotStarted extends CoreException
|
class SynchroExceptionNotStarted extends CoreException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -6,4 +7,4 @@
|
|||||||
|
|
||||||
class UserRightException extends CoreException
|
class UserRightException extends CoreException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -6,4 +7,4 @@
|
|||||||
|
|
||||||
class DictException extends CoreException
|
class DictException extends CoreException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -8,9 +9,9 @@ class DictExceptionMissingString extends DictException
|
|||||||
{
|
{
|
||||||
public function __construct($sLanguageCode, $sStringCode)
|
public function __construct($sLanguageCode, $sStringCode)
|
||||||
{
|
{
|
||||||
$aContext = array();
|
$aContext = [];
|
||||||
$aContext['language_code'] = $sLanguageCode;
|
$aContext['language_code'] = $sLanguageCode;
|
||||||
$aContext['string_code'] = $sStringCode;
|
$aContext['string_code'] = $sStringCode;
|
||||||
parent::__construct('Missing localized string', $aContext);
|
parent::__construct('Missing localized string', $aContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -8,8 +9,8 @@ class DictExceptionUnknownLanguage extends DictException
|
|||||||
{
|
{
|
||||||
public function __construct($sLanguageCode)
|
public function __construct($sLanguageCode)
|
||||||
{
|
{
|
||||||
$aContext = array();
|
$aContext = [];
|
||||||
$aContext['language_code'] = $sLanguageCode;
|
$aContext['language_code'] = $sLanguageCode;
|
||||||
parent::__construct('Unknown localization language', $aContext);
|
parent::__construct('Unknown localization language', $aContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -6,5 +7,4 @@
|
|||||||
|
|
||||||
class iTopXmlException extends CoreException
|
class iTopXmlException extends CoreException
|
||||||
{
|
{
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -20,7 +21,7 @@ class MySQLException extends CoreException
|
|||||||
$aContext['mysql_errno'] = $oException->getCode();
|
$aContext['mysql_errno'] = $oException->getCode();
|
||||||
$this->code = $oException->getCode();
|
$this->code = $oException->getCode();
|
||||||
$aContext['mysql_error'] = $oException->getMessage();
|
$aContext['mysql_error'] = $oException->getMessage();
|
||||||
} else if ($oMysqli != null) {
|
} elseif ($oMysqli != null) {
|
||||||
$aContext['mysql_errno'] = $oMysqli->errno;
|
$aContext['mysql_errno'] = $oMysqli->errno;
|
||||||
$this->code = $oMysqli->errno;
|
$this->code = $oMysqli->errno;
|
||||||
$aContext['mysql_error'] = $oMysqli->error;
|
$aContext['mysql_error'] = $oMysqli->error;
|
||||||
@@ -36,4 +37,4 @@ class MySQLException extends CoreException
|
|||||||
error_reporting(0);
|
error_reporting(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -19,14 +20,14 @@ class MySQLHasGoneAwayException extends MySQLException
|
|||||||
*/
|
*/
|
||||||
public static function getErrorCodes()
|
public static function getErrorCodes()
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
2006,
|
2006,
|
||||||
2013,
|
2013,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct($sIssue, $aContext)
|
public function __construct($sIssue, $aContext)
|
||||||
{
|
{
|
||||||
parent::__construct($sIssue, $aContext, null);
|
parent::__construct($sIssue, $aContext, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -9,5 +10,4 @@
|
|||||||
*/
|
*/
|
||||||
class MySQLNoTransactionException extends MySQLException
|
class MySQLNoTransactionException extends MySQLException
|
||||||
{
|
{
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -11,5 +12,4 @@
|
|||||||
*/
|
*/
|
||||||
class MySQLQueryHasNoResultException extends MySQLException
|
class MySQLQueryHasNoResultException extends MySQLException
|
||||||
{
|
{
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -9,5 +10,4 @@
|
|||||||
*/
|
*/
|
||||||
class MySQLTransactionNotClosedException extends MySQLException
|
class MySQLTransactionNotClosedException extends MySQLException
|
||||||
{
|
{
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -12,4 +13,4 @@
|
|||||||
*/
|
*/
|
||||||
class ProcessException extends CoreException
|
class ProcessException extends CoreException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -13,4 +14,4 @@
|
|||||||
*/
|
*/
|
||||||
class ProcessFatalException extends CoreException
|
class ProcessFatalException extends CoreException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -9,4 +10,4 @@
|
|||||||
*/
|
*/
|
||||||
class ProcessInvalidConfigException extends ProcessException
|
class ProcessInvalidConfigException extends ProcessException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2024 Combodo SAS
|
* Copyright (C) 2013-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
@@ -22,8 +23,8 @@
|
|||||||
* @author Olivier DAIN <olivier.dain@combodo.com>
|
* @author Olivier DAIN <olivier.dain@combodo.com>
|
||||||
* @since 3.0.0 N°3588
|
* @since 3.0.0 N°3588
|
||||||
*/
|
*/
|
||||||
class FindStylesheetObject{
|
class FindStylesheetObject
|
||||||
|
{
|
||||||
//file URIs
|
//file URIs
|
||||||
private $aStylesheetFileURIs;
|
private $aStylesheetFileURIs;
|
||||||
|
|
||||||
@@ -64,7 +65,7 @@ class FindStylesheetObject{
|
|||||||
return $this->aStylesheetFileURIs;
|
return $this->aStylesheetFileURIs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetLastModified() : int
|
public function GetLastModified(): int
|
||||||
{
|
{
|
||||||
return $this->iLastModified;
|
return $this->iLastModified;
|
||||||
}
|
}
|
||||||
@@ -92,7 +93,8 @@ class FindStylesheetObject{
|
|||||||
$this->sLastStyleSheetPath = $sStylesheetFilePath;
|
$this->sLastStyleSheetPath = $sStylesheetFilePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function AlreadyFetched(string $sStylesheetFilePath) : bool {
|
public function AlreadyFetched(string $sStylesheetFilePath): bool
|
||||||
|
{
|
||||||
return in_array($sStylesheetFilePath, $this->aAllStylesheetFilePaths);
|
return in_array($sStylesheetFilePath, $this->aAllStylesheetFilePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,4 +113,4 @@ class FindStylesheetObject{
|
|||||||
{
|
{
|
||||||
$this->sLastStyleSheetPath = "";
|
$this->sLastStyleSheetPath = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// 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
|
// 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
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persistent class InputOutputTask
|
* Persistent class InputOutputTask
|
||||||
*
|
*
|
||||||
@@ -28,41 +28,40 @@ require_once(APPROOT.'/application/cmdbabstract.class.inc.php');
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This class manages the input/output tasks
|
* This class manages the input/output tasks
|
||||||
* for synchronizing information with external data sources
|
* for synchronizing information with external data sources
|
||||||
*/
|
*/
|
||||||
class InputOutputTask extends cmdbAbstractObject
|
class InputOutputTask extends cmdbAbstractObject
|
||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "application",
|
"category" => "application",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_iotask",
|
"db_table" => "priv_iotask",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
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("name", ["allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
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 AttributeString("description", ["allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => []]));
|
||||||
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("category", ["allowed_values" => new ValueSetEnum('Input, Ouput'), "sql" => "category", "default_value" => "Input", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
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_type", ["allowed_values" => new ValueSetEnum('File, Database, Web Service'), "sql" => "source_type", "default_value" => "File", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
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 AttributeEnum("source_subtype", ["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" => []]));
|
||||||
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 AttributeString("source_path", ["allowed_values" => null, "sql" => "source_path", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
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 AttributeClass("objects_class", ["class_category" => "", "more_values" => "", "sql" => "objects_class", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
|
||||||
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("test_mode", ["allowed_values" => new ValueSetEnum('Yes,No'), "sql" => "test_mode", "default_value" => 'No', "is_null_allowed" => false, "depends_on" => []]));
|
||||||
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("verbose_mode", ["allowed_values" => new ValueSetEnum('Yes,No'), "sql" => "verbose_mode", "default_value" => 'No', "is_null_allowed" => false, "depends_on" => []]));
|
||||||
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 AttributeEnum("options", ["allowed_values" => new ValueSetEnum('Full, Update Only, Creation Only'), "sql" => "options", "default_value" => 'Full', "is_null_allowed" => true, "depends_on" => []]));
|
||||||
|
|
||||||
// Display lists
|
// 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', ['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
|
MetaModel::Init_SetZListItems('list', ['description', 'category', 'objects_class', 'source_type', 'source_subtype', 'options']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'category', 'objects_class', 'source_type', 'source_subtype')); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', ['name', 'category', 'objects_class', 'source_type', 'source_subtype']); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype')); // Criteria of the advanced search form
|
MetaModel::Init_SetZListItems('advanced_search', ['name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype']); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWebPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWebPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -6,4 +7,4 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// cannot notify depreciation for now as this is still MASSIVELY used in iTop core !
|
// cannot notify depreciation for now as this is still MASSIVELY used in iTop core !
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/iTopWebPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/iTopWebPage.php, now loadable using autoloader');
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWizardWebPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWizardWebPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/iTopWizardWebPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/iTopWizardWebPage.php, now loadable using autoloader');
|
||||||
|
|||||||
@@ -18,23 +18,17 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
*/
|
*/
|
||||||
public function ListSupportedLoginModes()
|
public function ListSupportedLoginModes()
|
||||||
{
|
{
|
||||||
return array('basic');
|
return ['basic'];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function OnModeDetection(&$iErrorCode)
|
protected function OnModeDetection(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (!Session::IsSet('login_mode'))
|
if (!Session::IsSet('login_mode')) {
|
||||||
{
|
if (isset($_SERVER['HTTP_AUTHORIZATION']) && !empty($_SERVER['HTTP_AUTHORIZATION'])) {
|
||||||
if (isset($_SERVER['HTTP_AUTHORIZATION']) && !empty($_SERVER['HTTP_AUTHORIZATION']))
|
|
||||||
{
|
|
||||||
Session::Set('login_mode', 'basic');
|
Session::Set('login_mode', 'basic');
|
||||||
}
|
} elseif (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && !empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
|
||||||
elseif (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && !empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION']))
|
|
||||||
{
|
|
||||||
Session::Set('login_mode', 'basic');
|
Session::Set('login_mode', 'basic');
|
||||||
}
|
} elseif (isset($_SERVER['PHP_AUTH_USER'])) {
|
||||||
elseif (isset($_SERVER['PHP_AUTH_USER']))
|
|
||||||
{
|
|
||||||
Session::Set('login_mode', 'basic');
|
Session::Set('login_mode', 'basic');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,22 +37,18 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnReadCredentials(&$iErrorCode)
|
protected function OnReadCredentials(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (!Session::IsSet('login_mode') || Session::Get('login_mode') == 'basic')
|
if (!Session::IsSet('login_mode') || Session::Get('login_mode') == 'basic') {
|
||||||
{
|
|
||||||
list($sAuthUser) = $this->GetAuthUserAndPassword();
|
list($sAuthUser) = $this->GetAuthUserAndPassword();
|
||||||
Session::Set('login_temp_auth_user', $sAuthUser);
|
Session::Set('login_temp_auth_user', $sAuthUser);
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected function OnCheckCredentials(&$iErrorCode)
|
protected function OnCheckCredentials(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'basic')
|
if (Session::Get('login_mode') == 'basic') {
|
||||||
{
|
|
||||||
list($sAuthUser, $sAuthPwd) = $this->GetAuthUserAndPassword();
|
list($sAuthUser, $sAuthPwd) = $this->GetAuthUserAndPassword();
|
||||||
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal'))
|
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal')) {
|
||||||
{
|
|
||||||
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
||||||
return LoginWebPage::LOGIN_FSM_ERROR;
|
return LoginWebPage::LOGIN_FSM_ERROR;
|
||||||
}
|
}
|
||||||
@@ -69,8 +59,7 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnCredentialsOK(&$iErrorCode)
|
protected function OnCredentialsOK(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'basic')
|
if (Session::Get('login_mode') == 'basic') {
|
||||||
{
|
|
||||||
LoginWebPage::OnLoginSuccess(Session::Get('auth_user'), 'internal', Session::Get('login_mode'));
|
LoginWebPage::OnLoginSuccess(Session::Get('auth_user'), 'internal', Session::Get('login_mode'));
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
@@ -78,13 +67,11 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnError(&$iErrorCode)
|
protected function OnError(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'basic')
|
if (Session::Get('login_mode') == 'basic') {
|
||||||
{
|
$iOnExit = LoginWebPage::getIOnExit();
|
||||||
$iOnExit = LoginWebPage::getIOnExit();
|
if ($iOnExit === LoginWebPage::EXIT_RETURN) {
|
||||||
if ($iOnExit === LoginWebPage::EXIT_RETURN)
|
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
|
||||||
{
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
|
|
||||||
}
|
|
||||||
LoginWebPage::HTTP401Error();
|
LoginWebPage::HTTP401Error();
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
@@ -92,8 +79,7 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnConnected(&$iErrorCode)
|
protected function OnConnected(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'basic')
|
if (Session::Get('login_mode') == 'basic') {
|
||||||
{
|
|
||||||
Session::Set('can_logoff', true);
|
Session::Set('can_logoff', true);
|
||||||
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
||||||
}
|
}
|
||||||
@@ -105,42 +91,33 @@ class LoginBasic extends AbstractLoginFSMExtension
|
|||||||
$sAuthUser = '';
|
$sAuthUser = '';
|
||||||
$sAuthPwd = null;
|
$sAuthPwd = null;
|
||||||
$sAuthorization = '';
|
$sAuthorization = '';
|
||||||
if (isset($_SERVER['HTTP_AUTHORIZATION']) && !empty($_SERVER['HTTP_AUTHORIZATION']))
|
if (isset($_SERVER['HTTP_AUTHORIZATION']) && !empty($_SERVER['HTTP_AUTHORIZATION'])) {
|
||||||
{
|
|
||||||
$sAuthorization = $_SERVER['HTTP_AUTHORIZATION'];
|
$sAuthorization = $_SERVER['HTTP_AUTHORIZATION'];
|
||||||
}
|
} elseif (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && !empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
|
||||||
elseif (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && !empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION']))
|
|
||||||
{
|
|
||||||
$sAuthorization = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
|
$sAuthorization = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($sAuthorization))
|
if (!empty($sAuthorization)) {
|
||||||
{
|
|
||||||
list($sAuthUser, $sAuthPwd) = explode(':', base64_decode(substr($sAuthorization, 6)));
|
list($sAuthUser, $sAuthPwd) = explode(':', base64_decode(substr($sAuthorization, 6)));
|
||||||
}
|
} else {
|
||||||
else
|
if (isset($_SERVER['PHP_AUTH_USER'])) {
|
||||||
{
|
|
||||||
if (isset($_SERVER['PHP_AUTH_USER']))
|
|
||||||
{
|
|
||||||
$sAuthUser = $_SERVER['PHP_AUTH_USER'];
|
$sAuthUser = $_SERVER['PHP_AUTH_USER'];
|
||||||
// Unfortunately, the RFC is not clear about the encoding...
|
// Unfortunately, the RFC is not clear about the encoding...
|
||||||
// IE and FF supply the user and password encoded in ISO-8859-1 whereas Chrome provides them encoded in UTF-8
|
// IE and FF supply the user and password encoded in ISO-8859-1 whereas Chrome provides them encoded in UTF-8
|
||||||
// So let's try to guess if it's an UTF-8 string or not... fortunately all encodings share the same ASCII base
|
// So let's try to guess if it's an UTF-8 string or not... fortunately all encodings share the same ASCII base
|
||||||
if (!LoginWebPage::LooksLikeUTF8($sAuthUser))
|
if (!LoginWebPage::LooksLikeUTF8($sAuthUser)) {
|
||||||
{
|
|
||||||
// Does not look like and UTF-8 string, try to convert it from iso-8859-1 to UTF-8
|
// Does not look like and UTF-8 string, try to convert it from iso-8859-1 to UTF-8
|
||||||
// Supposed to be harmless in case of a plain ASCII string...
|
// Supposed to be harmless in case of a plain ASCII string...
|
||||||
$sAuthUser = iconv('iso-8859-1', 'utf-8', $sAuthUser);
|
$sAuthUser = iconv('iso-8859-1', 'utf-8', $sAuthUser);
|
||||||
}
|
}
|
||||||
$sAuthPwd = $_SERVER['PHP_AUTH_PW'];
|
$sAuthPwd = $_SERVER['PHP_AUTH_PW'];
|
||||||
if (!LoginWebPage::LooksLikeUTF8($sAuthPwd))
|
if (!LoginWebPage::LooksLikeUTF8($sAuthPwd)) {
|
||||||
{
|
|
||||||
// Does not look like and UTF-8 string, try to convert it from iso-8859-1 to UTF-8
|
// Does not look like and UTF-8 string, try to convert it from iso-8859-1 to UTF-8
|
||||||
// Supposed to be harmless in case of a plain ASCII string...
|
// Supposed to be harmless in case of a plain ASCII string...
|
||||||
$sAuthPwd = iconv('iso-8859-1', 'utf-8', $sAuthPwd);
|
$sAuthPwd = iconv('iso-8859-1', 'utf-8', $sAuthPwd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return array($sAuthUser, $sAuthPwd);
|
return [$sAuthUser, $sAuthPwd];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -18,7 +19,7 @@ class LoginDefaultBefore extends AbstractLoginFSMExtension
|
|||||||
*/
|
*/
|
||||||
public function ListSupportedLoginModes()
|
public function ListSupportedLoginModes()
|
||||||
{
|
{
|
||||||
return array('before');
|
return ['before'];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function OnStart(&$iErrorCode)
|
protected function OnStart(&$iErrorCode)
|
||||||
@@ -31,13 +32,10 @@ class LoginDefaultBefore extends AbstractLoginFSMExtension
|
|||||||
$aAllowedLoginTypes = MetaModel::GetConfig()->GetAllowedLoginTypes();
|
$aAllowedLoginTypes = MetaModel::GetConfig()->GetAllowedLoginTypes();
|
||||||
$sProposedLoginMode = utils::ReadParam('login_mode', '');
|
$sProposedLoginMode = utils::ReadParam('login_mode', '');
|
||||||
$index = array_search($sProposedLoginMode, $aAllowedLoginTypes);
|
$index = array_search($sProposedLoginMode, $aAllowedLoginTypes);
|
||||||
if ($index !== false)
|
if ($index !== false) {
|
||||||
{
|
|
||||||
// Force login mode
|
// Force login mode
|
||||||
Session::Set('login_mode', $sProposedLoginMode);
|
Session::Set('login_mode', $sProposedLoginMode);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
Session::Unset('login_mode');
|
Session::Unset('login_mode');
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
@@ -49,8 +47,7 @@ class LoginDefaultBefore extends AbstractLoginFSMExtension
|
|||||||
$aAllowedLoginTypes = MetaModel::GetConfig()->GetAllowedLoginTypes();
|
$aAllowedLoginTypes = MetaModel::GetConfig()->GetAllowedLoginTypes();
|
||||||
$sProposedLoginMode = utils::ReadParam('login_mode', '');
|
$sProposedLoginMode = utils::ReadParam('login_mode', '');
|
||||||
$index = array_search($sProposedLoginMode, $aAllowedLoginTypes);
|
$index = array_search($sProposedLoginMode, $aAllowedLoginTypes);
|
||||||
if ($index !== false)
|
if ($index !== false) {
|
||||||
{
|
|
||||||
// Force login mode
|
// Force login mode
|
||||||
LoginWebPage::SetLoginModeAndReload($sProposedLoginMode);
|
LoginWebPage::SetLoginModeAndReload($sProposedLoginMode);
|
||||||
} else {
|
} else {
|
||||||
@@ -69,8 +66,6 @@ class LoginDefaultBefore extends AbstractLoginFSMExtension
|
|||||||
*/
|
*/
|
||||||
class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExtension
|
class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExtension
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must be executed after the other login plugins
|
* Must be executed after the other login plugins
|
||||||
*
|
*
|
||||||
@@ -78,19 +73,16 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
|
|||||||
*/
|
*/
|
||||||
public function ListSupportedLoginModes()
|
public function ListSupportedLoginModes()
|
||||||
{
|
{
|
||||||
return array('after');
|
return ['after'];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function OnError(&$iErrorCode)
|
protected function OnError(&$iErrorCode)
|
||||||
{
|
{
|
||||||
self::ResetLoginSession();
|
self::ResetLoginSession();
|
||||||
$iOnExit = LoginWebPage::getIOnExit();
|
$iOnExit = LoginWebPage::getIOnExit();
|
||||||
if ($iOnExit === LoginWebPage::EXIT_RETURN)
|
if ($iOnExit === LoginWebPage::EXIT_RETURN) {
|
||||||
{
|
|
||||||
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
|
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
|
||||||
}
|
} elseif ($iOnExit == LoginWebPage::EXIT_HTTP_401) {
|
||||||
elseif ($iOnExit == LoginWebPage::EXIT_HTTP_401)
|
|
||||||
{
|
|
||||||
LoginWebPage::HTTP401Error(); // Error, exit
|
LoginWebPage::HTTP401Error(); // Error, exit
|
||||||
}
|
}
|
||||||
// LoginWebPage::EXIT_PROMPT
|
// LoginWebPage::EXIT_PROMPT
|
||||||
@@ -99,13 +91,12 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
|
|||||||
|
|
||||||
protected function OnCredentialsOk(&$iErrorCode)
|
protected function OnCredentialsOk(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (!Session::IsSet('login_mode'))
|
if (!Session::IsSet('login_mode')) {
|
||||||
{
|
// N°6358 - if EXIT_RETURN was asked, send an error
|
||||||
// N°6358 - if EXIT_RETURN was asked, send an error
|
if (LoginWebPage::getIOnExit() === LoginWebPage::EXIT_RETURN) {
|
||||||
if (LoginWebPage::getIOnExit() === LoginWebPage::EXIT_RETURN) {
|
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
||||||
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
return LoginWebPage::LOGIN_FSM_ERROR;
|
||||||
return LoginWebPage::LOGIN_FSM_ERROR;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If no plugin validated the user, exit
|
// If no plugin validated the user, exit
|
||||||
self::ResetLoginSession();
|
self::ResetLoginSession();
|
||||||
@@ -125,7 +116,7 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
|
|||||||
protected function OnConnected(&$iErrorCode)
|
protected function OnConnected(&$iErrorCode)
|
||||||
{
|
{
|
||||||
Session::Unset('login_temp_auth_user');
|
Session::Unset('login_temp_auth_user');
|
||||||
if (is_null(UserRights::GetUserObject())){
|
if (is_null(UserRights::GetUserObject())) {
|
||||||
//N°7085 avoid infinite loop
|
//N°7085 avoid infinite loop
|
||||||
IssueLog::Error("No user logged in. exit");
|
IssueLog::Error("No user logged in. exit");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@@ -137,10 +128,8 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
|
|||||||
private static function ResetLoginSession()
|
private static function ResetLoginSession()
|
||||||
{
|
{
|
||||||
LoginWebPage::ResetSession();
|
LoginWebPage::ResetSession();
|
||||||
foreach (Session::ListVariables() as $sKey)
|
foreach (Session::ListVariables() as $sKey) {
|
||||||
{
|
if (utils::StartsWith($sKey, 'login_')) {
|
||||||
if (utils::StartsWith($sKey, 'login_'))
|
|
||||||
{
|
|
||||||
Session::Unset($sKey);
|
Session::Unset($sKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ use Combodo\iTop\Application\Helper\Session;
|
|||||||
|
|
||||||
class LoginExternal extends AbstractLoginFSMExtension
|
class LoginExternal extends AbstractLoginFSMExtension
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the list of supported login modes for this plugin
|
* Return the list of supported login modes for this plugin
|
||||||
*
|
*
|
||||||
@@ -19,16 +18,14 @@ class LoginExternal extends AbstractLoginFSMExtension
|
|||||||
*/
|
*/
|
||||||
public function ListSupportedLoginModes()
|
public function ListSupportedLoginModes()
|
||||||
{
|
{
|
||||||
return array('external');
|
return ['external'];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function OnModeDetection(&$iErrorCode)
|
protected function OnModeDetection(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (!Session::IsSet('login_mode'))
|
if (!Session::IsSet('login_mode')) {
|
||||||
{
|
|
||||||
$sAuthUser = $this->GetAuthUser();
|
$sAuthUser = $this->GetAuthUser();
|
||||||
if ($sAuthUser && (strlen($sAuthUser) > 0))
|
if ($sAuthUser && (strlen($sAuthUser) > 0)) {
|
||||||
{
|
|
||||||
Session::Set('login_mode', 'external');
|
Session::Set('login_mode', 'external');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,11 +34,9 @@ class LoginExternal extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnCheckCredentials(&$iErrorCode)
|
protected function OnCheckCredentials(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'external')
|
if (Session::Get('login_mode') == 'external') {
|
||||||
{
|
|
||||||
$sAuthUser = $this->GetAuthUser();
|
$sAuthUser = $this->GetAuthUser();
|
||||||
if (!UserRights::CheckCredentials($sAuthUser, '', Session::Get('login_mode'), 'external'))
|
if (!UserRights::CheckCredentials($sAuthUser, '', Session::Get('login_mode'), 'external')) {
|
||||||
{
|
|
||||||
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
||||||
return LoginWebPage::LOGIN_FSM_ERROR;
|
return LoginWebPage::LOGIN_FSM_ERROR;
|
||||||
}
|
}
|
||||||
@@ -52,8 +47,7 @@ class LoginExternal extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnCredentialsOK(&$iErrorCode)
|
protected function OnCredentialsOK(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'external')
|
if (Session::Get('login_mode') == 'external') {
|
||||||
{
|
|
||||||
LoginWebPage::OnLoginSuccess(Session::Get('auth_user'), 'external', Session::Get('login_mode'));
|
LoginWebPage::OnLoginSuccess(Session::Get('auth_user'), 'external', Session::Get('login_mode'));
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
@@ -61,8 +55,7 @@ class LoginExternal extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnConnected(&$iErrorCode)
|
protected function OnConnected(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'external')
|
if (Session::Get('login_mode') == 'external') {
|
||||||
{
|
|
||||||
Session::Set('can_logoff', false);
|
Session::Set('can_logoff', false);
|
||||||
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
||||||
}
|
}
|
||||||
@@ -71,13 +64,11 @@ class LoginExternal extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnError(&$iErrorCode)
|
protected function OnError(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'external')
|
if (Session::Get('login_mode') == 'external') {
|
||||||
{
|
$iOnExit = LoginWebPage::getIOnExit();
|
||||||
$iOnExit = LoginWebPage::getIOnExit();
|
if ($iOnExit === LoginWebPage::EXIT_RETURN) {
|
||||||
if ($iOnExit === LoginWebPage::EXIT_RETURN)
|
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
|
||||||
{
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
|
|
||||||
}
|
|
||||||
LoginWebPage::HTTP401Error();
|
LoginWebPage::HTTP401Error();
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
|
|||||||
*/
|
*/
|
||||||
public function ListSupportedLoginModes()
|
public function ListSupportedLoginModes()
|
||||||
{
|
{
|
||||||
return array('form');
|
return ['form'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,19 +34,17 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
|
|||||||
if (!Session::IsSet('login_mode') || Session::Get('login_mode') == 'form') {
|
if (!Session::IsSet('login_mode') || Session::Get('login_mode') == 'form') {
|
||||||
$sAuthUser = utils::ReadPostedParam('auth_user', '', 'raw_data');
|
$sAuthUser = utils::ReadPostedParam('auth_user', '', 'raw_data');
|
||||||
$sAuthPwd = utils::ReadPostedParam('auth_pwd', null, 'raw_data');
|
$sAuthPwd = utils::ReadPostedParam('auth_pwd', null, 'raw_data');
|
||||||
if ($this->bForceFormOnError || empty($sAuthUser) || empty($sAuthPwd))
|
if ($this->bForceFormOnError || empty($sAuthUser) || empty($sAuthPwd)) {
|
||||||
{
|
if (array_key_exists('HTTP_X_COMBODO_AJAX', $_SERVER)) {
|
||||||
if (array_key_exists('HTTP_X_COMBODO_AJAX', $_SERVER))
|
|
||||||
{
|
|
||||||
// X-Combodo-Ajax is a special header automatically added to all ajax requests
|
// X-Combodo-Ajax is a special header automatically added to all ajax requests
|
||||||
// Let's reply that we're currently logged-out
|
// Let's reply that we're currently logged-out
|
||||||
header('HTTP/1.0 401 Unauthorized');
|
header('HTTP/1.0 401 Unauthorized');
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LoginWebPage::getIOnExit() === LoginWebPage::EXIT_RETURN) {
|
if (LoginWebPage::getIOnExit() === LoginWebPage::EXIT_RETURN) {
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No credentials yet, display the form
|
// No credentials yet, display the form
|
||||||
$oPage = LoginWebPage::NewLoginWebPage();
|
$oPage = LoginWebPage::NewLoginWebPage();
|
||||||
@@ -66,12 +64,10 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
|
|||||||
*/
|
*/
|
||||||
protected function OnCheckCredentials(&$iErrorCode)
|
protected function OnCheckCredentials(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'form')
|
if (Session::Get('login_mode') == 'form') {
|
||||||
{
|
|
||||||
$sAuthUser = utils::ReadPostedParam('auth_user', '', 'raw_data');
|
$sAuthUser = utils::ReadPostedParam('auth_user', '', 'raw_data');
|
||||||
$sAuthPwd = utils::ReadPostedParam('auth_pwd', null, 'raw_data');
|
$sAuthPwd = utils::ReadPostedParam('auth_pwd', null, 'raw_data');
|
||||||
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal'))
|
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal')) {
|
||||||
{
|
|
||||||
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
||||||
return LoginWebPage::LOGIN_FSM_ERROR;
|
return LoginWebPage::LOGIN_FSM_ERROR;
|
||||||
}
|
}
|
||||||
@@ -85,8 +81,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
|
|||||||
*/
|
*/
|
||||||
protected function OnCredentialsOK(&$iErrorCode)
|
protected function OnCredentialsOK(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'form')
|
if (Session::Get('login_mode') == 'form') {
|
||||||
{
|
|
||||||
// Store 'auth_user' in session for further use
|
// Store 'auth_user' in session for further use
|
||||||
LoginWebPage::OnLoginSuccess(Session::Get('auth_user'), 'internal', Session::Get('login_mode'));
|
LoginWebPage::OnLoginSuccess(Session::Get('auth_user'), 'internal', Session::Get('login_mode'));
|
||||||
}
|
}
|
||||||
@@ -98,8 +93,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
|
|||||||
*/
|
*/
|
||||||
protected function OnError(&$iErrorCode)
|
protected function OnError(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'form')
|
if (Session::Get('login_mode') == 'form') {
|
||||||
{
|
|
||||||
$this->bForceFormOnError = true;
|
$this->bForceFormOnError = true;
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
@@ -110,8 +104,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
|
|||||||
*/
|
*/
|
||||||
protected function OnConnected(&$iErrorCode)
|
protected function OnConnected(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'form')
|
if (Session::Get('login_mode') == 'form') {
|
||||||
{
|
|
||||||
Session::Set('can_logoff', true);
|
Session::Set('can_logoff', true);
|
||||||
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
||||||
}
|
}
|
||||||
@@ -131,24 +124,23 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
|
|||||||
$sAuthUser = utils::ReadParam('auth_user', '', true, 'raw_data');
|
$sAuthUser = utils::ReadParam('auth_user', '', true, 'raw_data');
|
||||||
$sAuthPwd = utils::ReadParam('suggest_pwd', '', true, 'raw_data');
|
$sAuthPwd = utils::ReadParam('suggest_pwd', '', true, 'raw_data');
|
||||||
|
|
||||||
$aData = array(
|
$aData = [
|
||||||
'sAuthUser' => $sAuthUser,
|
'sAuthUser' => $sAuthUser,
|
||||||
'sAuthPwd' => $sAuthPwd,
|
'sAuthPwd' => $sAuthPwd,
|
||||||
);
|
];
|
||||||
$oLoginContext->AddBlockExtension('login_input', new LoginBlockExtension('extensionblock/loginforminput.html.twig', $aData));
|
$oLoginContext->AddBlockExtension('login_input', new LoginBlockExtension('extensionblock/loginforminput.html.twig', $aData));
|
||||||
$oLoginContext->AddBlockExtension('login_submit', new LoginBlockExtension('extensionblock/loginformsubmit.html.twig'));
|
$oLoginContext->AddBlockExtension('login_submit', new LoginBlockExtension('extensionblock/loginformsubmit.html.twig'));
|
||||||
$oLoginContext->AddBlockExtension('login_form_footer', new LoginBlockExtension('extensionblock/loginformfooter.html.twig'));
|
$oLoginContext->AddBlockExtension('login_form_footer', new LoginBlockExtension('extensionblock/loginformfooter.html.twig'));
|
||||||
|
|
||||||
$bEnableResetPassword = MetaModel::GetConfig()->Get('forgot_password');
|
$bEnableResetPassword = MetaModel::GetConfig()->Get('forgot_password');
|
||||||
$sResetPasswordUrl = MetaModel::GetConfig()->Get('forgot_password.url');
|
$sResetPasswordUrl = MetaModel::GetConfig()->Get('forgot_password.url');
|
||||||
if ($sResetPasswordUrl == '')
|
if ($sResetPasswordUrl == '') {
|
||||||
{
|
$sResetPasswordUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?loginop=forgot_pwd';
|
||||||
$sResetPasswordUrl = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?loginop=forgot_pwd';
|
|
||||||
}
|
}
|
||||||
$aData = array(
|
$aData = [
|
||||||
'bEnableResetPassword' => $bEnableResetPassword,
|
'bEnableResetPassword' => $bEnableResetPassword,
|
||||||
'sResetPasswordUrl' => $sResetPasswordUrl,
|
'sResetPasswordUrl' => $sResetPasswordUrl,
|
||||||
);
|
];
|
||||||
$oLoginContext->AddBlockExtension('login_links', new LoginBlockExtension('extensionblock/loginformlinks.html.twig', $aData));
|
$oLoginContext->AddBlockExtension('login_links', new LoginBlockExtension('extensionblock/loginformlinks.html.twig', $aData));
|
||||||
|
|
||||||
return $oLoginContext;
|
return $oLoginContext;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
use Combodo\iTop\Application\Branding;
|
use Combodo\iTop\Application\Branding;
|
||||||
use Combodo\iTop\Application\TwigBase\Twig\Extension;
|
use Combodo\iTop\Application\TwigBase\Twig\Extension;
|
||||||
use Combodo\iTop\Application\WebPage\NiceWebPage;
|
use Combodo\iTop\Application\WebPage\NiceWebPage;
|
||||||
@@ -41,11 +40,11 @@ class LoginTwigContext
|
|||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->aBlockExtension = array();
|
$this->aBlockExtension = [];
|
||||||
$this->aPostedVars = array();
|
$this->aPostedVars = [];
|
||||||
$this->sTwigLoaderPath = null;
|
$this->sTwigLoaderPath = null;
|
||||||
$this->aCSSFiles = array();
|
$this->aCSSFiles = [];
|
||||||
$this->aJsFiles = array();
|
$this->aJsFiles = [];
|
||||||
$this->sTwigNameSpace = null;
|
$this->sTwigNameSpace = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +178,7 @@ class LoginBlockExtension
|
|||||||
* @param array $aData Data given to the twig template (into the variable {{ aData }})
|
* @param array $aData Data given to the twig template (into the variable {{ aData }})
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function __construct($sTwig, $aData = array())
|
public function __construct($sTwig, $aData = [])
|
||||||
{
|
{
|
||||||
$this->sTwig = $sTwig;
|
$this->sTwig = $sTwig;
|
||||||
$this->aData = $aData;
|
$this->aData = $aData;
|
||||||
@@ -210,21 +209,18 @@ class LoginTwigRenderer
|
|||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->aLoginPluginList = LoginWebPage::GetLoginPluginList('iLoginUIExtension', false);
|
$this->aLoginPluginList = LoginWebPage::GetLoginPluginList('iLoginUIExtension', false);
|
||||||
$this->aPluginFormData = array();
|
$this->aPluginFormData = [];
|
||||||
$aTwigLoaders = array();
|
$aTwigLoaders = [];
|
||||||
$this->aPostedVars = array();
|
$this->aPostedVars = [];
|
||||||
foreach ($this->aLoginPluginList as $oLoginPlugin)
|
foreach ($this->aLoginPluginList as $oLoginPlugin) {
|
||||||
{
|
|
||||||
/** @var \iLoginUIExtension $oLoginPlugin */
|
/** @var \iLoginUIExtension $oLoginPlugin */
|
||||||
$oLoginContext = $oLoginPlugin->GetTwigContext();
|
$oLoginContext = $oLoginPlugin->GetTwigContext();
|
||||||
if (is_null($oLoginContext))
|
if (is_null($oLoginContext)) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$this->aPluginFormData[] = $oLoginContext;
|
$this->aPluginFormData[] = $oLoginContext;
|
||||||
$sTwigLoaderPath = $oLoginContext->GetTwigLoaderPath();
|
$sTwigLoaderPath = $oLoginContext->GetTwigLoaderPath();
|
||||||
if ($sTwigLoaderPath != null)
|
if ($sTwigLoaderPath != null) {
|
||||||
{
|
|
||||||
$oExtensionLoader = new FilesystemLoader();
|
$oExtensionLoader = new FilesystemLoader();
|
||||||
$oExtensionLoader->setPaths($sTwigLoaderPath);
|
$oExtensionLoader->setPaths($sTwigLoaderPath);
|
||||||
$aTwigLoaders[] = $oExtensionLoader;
|
$aTwigLoaders[] = $oExtensionLoader;
|
||||||
@@ -232,8 +228,8 @@ class LoginTwigRenderer
|
|||||||
$this->aPostedVars = array_merge($this->aPostedVars, $oLoginContext->GetPostedVars());
|
$this->aPostedVars = array_merge($this->aPostedVars, $oLoginContext->GetPostedVars());
|
||||||
}
|
}
|
||||||
|
|
||||||
$oCoreLoader = new FilesystemLoader(array(), APPROOT.'templates');
|
$oCoreLoader = new FilesystemLoader([], APPROOT.'templates');
|
||||||
$aCoreTemplatesPaths = array('pages/login', 'pages/login/password');
|
$aCoreTemplatesPaths = ['pages/login', 'pages/login/password'];
|
||||||
// Having this path declared after the plugins let the plugins replace the core templates
|
// Having this path declared after the plugins let the plugins replace the core templates
|
||||||
$oCoreLoader->setPaths($aCoreTemplatesPaths);
|
$oCoreLoader->setPaths($aCoreTemplatesPaths);
|
||||||
// Having the core templates accessible within a different namespace offer the possibility to extend them while replacing them
|
// Having the core templates accessible within a different namespace offer the possibility to extend them while replacing them
|
||||||
@@ -251,19 +247,19 @@ class LoginTwigRenderer
|
|||||||
$sIconUrl = Utils::GetConfig()->Get('app_icon_url');
|
$sIconUrl = Utils::GetConfig()->Get('app_icon_url');
|
||||||
$sDisplayIcon = Branding::GetLoginLogoAbsoluteUrl();
|
$sDisplayIcon = Branding::GetLoginLogoAbsoluteUrl();
|
||||||
|
|
||||||
$aVars = array(
|
$aVars = [
|
||||||
'sAppRootUrl' => utils::GetAbsoluteUrlAppRoot(),
|
'sAppRootUrl' => utils::GetAbsoluteUrlAppRoot(),
|
||||||
'aPluginFormData' => $this->GetPluginFormData(),
|
'aPluginFormData' => $this->GetPluginFormData(),
|
||||||
'sItopVersion' => ITOP_VERSION,
|
'sItopVersion' => ITOP_VERSION,
|
||||||
'sVersionShort' => $sVersionShort,
|
'sVersionShort' => $sVersionShort,
|
||||||
'sIconUrl' => $sIconUrl,
|
'sIconUrl' => $sIconUrl,
|
||||||
'sDisplayIcon' => $sDisplayIcon,
|
'sDisplayIcon' => $sDisplayIcon,
|
||||||
);
|
];
|
||||||
|
|
||||||
return $aVars;
|
return $aVars;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Render(NiceWebPage $oPage, $sTwigFile, $aVars = array())
|
public function Render(NiceWebPage $oPage, $sTwigFile, $aVars = [])
|
||||||
{
|
{
|
||||||
$oTemplate = $this->GetTwig()->load($sTwigFile);
|
$oTemplate = $this->GetTwig()->load($sTwigFile);
|
||||||
$oPage->add($oTemplate->renderBlock('body', $aVars));
|
$oPage->add($oTemplate->renderBlock('body', $aVars));
|
||||||
@@ -272,17 +268,14 @@ class LoginTwigRenderer
|
|||||||
$oPage->add_style($oTemplate->renderBlock('css', $aVars));
|
$oPage->add_style($oTemplate->renderBlock('css', $aVars));
|
||||||
|
|
||||||
// Render CSS links
|
// Render CSS links
|
||||||
foreach ($this->aPluginFormData as $oFormData)
|
foreach ($this->aPluginFormData as $oFormData) {
|
||||||
{
|
|
||||||
/** @var \LoginTwigContext $oFormData */
|
/** @var \LoginTwigContext $oFormData */
|
||||||
$aCSSFiles = $oFormData->GetCSSFiles();
|
$aCSSFiles = $oFormData->GetCSSFiles();
|
||||||
foreach ($aCSSFiles as $sCSSFile)
|
foreach ($aCSSFiles as $sCSSFile) {
|
||||||
{
|
|
||||||
$oPage->LinkStylesheetFromURI($sCSSFile);
|
$oPage->LinkStylesheetFromURI($sCSSFile);
|
||||||
}
|
}
|
||||||
$aJsFiles = $oFormData->GetJsFiles();
|
$aJsFiles = $oFormData->GetJsFiles();
|
||||||
foreach ($aJsFiles as $sJsFile)
|
foreach ($aJsFiles as $sJsFile) {
|
||||||
{
|
|
||||||
$oPage->LinkScriptFromURI($sJsFile);
|
$oPage->LinkScriptFromURI($sJsFile);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,17 +23,15 @@ class LoginURL extends AbstractLoginFSMExtension
|
|||||||
*/
|
*/
|
||||||
public function ListSupportedLoginModes()
|
public function ListSupportedLoginModes()
|
||||||
{
|
{
|
||||||
return array('url');
|
return ['url'];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function OnModeDetection(&$iErrorCode)
|
protected function OnModeDetection(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (!Session::IsSet('login_mode') && !$this->bErrorOccurred)
|
if (!Session::IsSet('login_mode') && !$this->bErrorOccurred) {
|
||||||
{
|
|
||||||
$sAuthUser = utils::ReadParam('auth_user', '', false, 'raw_data');
|
$sAuthUser = utils::ReadParam('auth_user', '', false, 'raw_data');
|
||||||
$sAuthPwd = utils::ReadParam('auth_pwd', null, false, 'raw_data');
|
$sAuthPwd = utils::ReadParam('auth_pwd', null, false, 'raw_data');
|
||||||
if (!empty($sAuthUser) && !empty($sAuthPwd))
|
if (!empty($sAuthUser) && !empty($sAuthPwd)) {
|
||||||
{
|
|
||||||
Session::Set('login_mode', 'url');
|
Session::Set('login_mode', 'url');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,8 +40,7 @@ class LoginURL extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnReadCredentials(&$iErrorCode)
|
protected function OnReadCredentials(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'url')
|
if (Session::Get('login_mode') == 'url') {
|
||||||
{
|
|
||||||
Session::Set('login_temp_auth_user', utils::ReadParam('auth_user', '', false, 'raw_data'));
|
Session::Set('login_temp_auth_user', utils::ReadParam('auth_user', '', false, 'raw_data'));
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
@@ -51,12 +48,10 @@ class LoginURL extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnCheckCredentials(&$iErrorCode)
|
protected function OnCheckCredentials(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'url')
|
if (Session::Get('login_mode') == 'url') {
|
||||||
{
|
|
||||||
$sAuthUser = utils::ReadParam('auth_user', '', false, 'raw_data');
|
$sAuthUser = utils::ReadParam('auth_user', '', false, 'raw_data');
|
||||||
$sAuthPwd = utils::ReadParam('auth_pwd', null, false, 'raw_data');
|
$sAuthPwd = utils::ReadParam('auth_pwd', null, false, 'raw_data');
|
||||||
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal'))
|
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal')) {
|
||||||
{
|
|
||||||
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
|
||||||
return LoginWebPage::LOGIN_FSM_ERROR;
|
return LoginWebPage::LOGIN_FSM_ERROR;
|
||||||
}
|
}
|
||||||
@@ -67,8 +62,7 @@ class LoginURL extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnCredentialsOK(&$iErrorCode)
|
protected function OnCredentialsOK(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'url')
|
if (Session::Get('login_mode') == 'url') {
|
||||||
{
|
|
||||||
LoginWebPage::OnLoginSuccess(Session::Get('auth_user'), 'internal', Session::Get('login_mode'));
|
LoginWebPage::OnLoginSuccess(Session::Get('auth_user'), 'internal', Session::Get('login_mode'));
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
@@ -76,8 +70,7 @@ class LoginURL extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnError(&$iErrorCode)
|
protected function OnError(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'url')
|
if (Session::Get('login_mode') == 'url') {
|
||||||
{
|
|
||||||
$this->bErrorOccurred = true;
|
$this->bErrorOccurred = true;
|
||||||
}
|
}
|
||||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||||
@@ -85,8 +78,7 @@ class LoginURL extends AbstractLoginFSMExtension
|
|||||||
|
|
||||||
protected function OnConnected(&$iErrorCode)
|
protected function OnConnected(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == 'url')
|
if (Session::Get('login_mode') == 'url') {
|
||||||
{
|
|
||||||
Session::Set('can_logoff', true);
|
Session::Set('can_logoff', true);
|
||||||
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// 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
|
// 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
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class LoginWebPage
|
* Class LoginWebPage
|
||||||
*
|
*
|
||||||
@@ -37,33 +37,33 @@ use Combodo\iTop\Service\Events\EventService;
|
|||||||
|
|
||||||
class LoginWebPage extends NiceWebPage
|
class LoginWebPage extends NiceWebPage
|
||||||
{
|
{
|
||||||
const EXIT_PROMPT = 0;
|
public const EXIT_PROMPT = 0;
|
||||||
const EXIT_HTTP_401 = 1;
|
public const EXIT_HTTP_401 = 1;
|
||||||
const EXIT_RETURN = 2;
|
public const EXIT_RETURN = 2;
|
||||||
|
|
||||||
const EXIT_CODE_OK = 0;
|
public const EXIT_CODE_OK = 0;
|
||||||
const EXIT_CODE_MISSINGLOGIN = 1;
|
public const EXIT_CODE_MISSINGLOGIN = 1;
|
||||||
const EXIT_CODE_MISSINGPASSWORD = 2;
|
public const EXIT_CODE_MISSINGPASSWORD = 2;
|
||||||
const EXIT_CODE_WRONGCREDENTIALS = 3;
|
public const EXIT_CODE_WRONGCREDENTIALS = 3;
|
||||||
const EXIT_CODE_MUSTBEADMIN = 4;
|
public const EXIT_CODE_MUSTBEADMIN = 4;
|
||||||
const EXIT_CODE_PORTALUSERNOTAUTHORIZED = 5;
|
public const EXIT_CODE_PORTALUSERNOTAUTHORIZED = 5;
|
||||||
const EXIT_CODE_NOTAUTHORIZED = 6;
|
public const EXIT_CODE_NOTAUTHORIZED = 6;
|
||||||
|
|
||||||
// Login FSM States
|
// Login FSM States
|
||||||
const LOGIN_STATE_START = 'start'; // Entry state
|
public const LOGIN_STATE_START = 'start'; // Entry state
|
||||||
const LOGIN_STATE_MODE_DETECTION = 'login mode detection'; // Detect which login plugin to use
|
public const LOGIN_STATE_MODE_DETECTION = 'login mode detection'; // Detect which login plugin to use
|
||||||
const LOGIN_STATE_READ_CREDENTIALS = 'read credentials'; // Read the credentials
|
public const LOGIN_STATE_READ_CREDENTIALS = 'read credentials'; // Read the credentials
|
||||||
const LOGIN_STATE_CHECK_CREDENTIALS = 'check credentials'; // Check if the credentials are valid
|
public const LOGIN_STATE_CHECK_CREDENTIALS = 'check credentials'; // Check if the credentials are valid
|
||||||
const LOGIN_STATE_CREDENTIALS_OK = 'credentials ok'; // User provisioning
|
public const LOGIN_STATE_CREDENTIALS_OK = 'credentials ok'; // User provisioning
|
||||||
const LOGIN_STATE_USER_OK = 'user ok'; // Additional check (2FA)
|
public const LOGIN_STATE_USER_OK = 'user ok'; // Additional check (2FA)
|
||||||
const LOGIN_STATE_CONNECTED = 'connected'; // User connected
|
public const LOGIN_STATE_CONNECTED = 'connected'; // User connected
|
||||||
const LOGIN_STATE_SET_ERROR = 'prepare for error'; // Internal state to trigger ERROR state
|
public const LOGIN_STATE_SET_ERROR = 'prepare for error'; // Internal state to trigger ERROR state
|
||||||
const LOGIN_STATE_ERROR = 'error'; // An error occurred, next state will be NONE
|
public const LOGIN_STATE_ERROR = 'error'; // An error occurred, next state will be NONE
|
||||||
|
|
||||||
// Login FSM Returns
|
// Login FSM Returns
|
||||||
const LOGIN_FSM_RETURN = 0; // End the FSM OK (connected)
|
public const LOGIN_FSM_RETURN = 0; // End the FSM OK (connected)
|
||||||
const LOGIN_FSM_ERROR = 1; // Error signaled
|
public const LOGIN_FSM_ERROR = 1; // Error signaled
|
||||||
const LOGIN_FSM_CONTINUE = 2; // Continue FSM
|
public const LOGIN_FSM_CONTINUE = 2; // Continue FSM
|
||||||
|
|
||||||
protected static $sHandlerClass = __class__;
|
protected static $sHandlerClass = __class__;
|
||||||
private static $iOnExit;
|
private static $iOnExit;
|
||||||
@@ -78,7 +78,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
*/
|
*/
|
||||||
public static function NewLoginWebPage()
|
public static function NewLoginWebPage()
|
||||||
{
|
{
|
||||||
return new self::$sHandlerClass;
|
return new self::$sHandlerClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static $m_sLoginFailedMessage = '';
|
protected static $m_sLoginFailedMessage = '';
|
||||||
@@ -94,7 +94,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$this->no_cache();
|
$this->no_cache();
|
||||||
$this->add_http_headers();
|
$this->add_http_headers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SetStyleSheet()
|
public function SetStyleSheet()
|
||||||
{
|
{
|
||||||
$this->LinkStylesheetFromAppRoot('css/login.css');
|
$this->LinkStylesheetFromAppRoot('css/login.css');
|
||||||
@@ -128,23 +128,18 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$oProfilesSet = $oUser->Get('profile_list');
|
$oProfilesSet = $oUser->Get('profile_list');
|
||||||
//delete old profiles
|
//delete old profiles
|
||||||
$aExistingProfiles = [];
|
$aExistingProfiles = [];
|
||||||
while ($oProfile = $oProfilesSet->Fetch())
|
while ($oProfile = $oProfilesSet->Fetch()) {
|
||||||
{
|
|
||||||
array_push($aExistingProfiles, $oProfile->Get('profileid'));
|
array_push($aExistingProfiles, $oProfile->Get('profileid'));
|
||||||
$iArrayKey = array_search($oProfile->Get('profileid'), $aProfiles);
|
$iArrayKey = array_search($oProfile->Get('profileid'), $aProfiles);
|
||||||
if (!$iArrayKey)
|
if (!$iArrayKey) {
|
||||||
{
|
|
||||||
$oProfilesSet->RemoveItem($oProfile->Get('profileid'));
|
$oProfilesSet->RemoveItem($oProfile->Get('profileid'));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
unset($aProfiles[$iArrayKey]);
|
unset($aProfiles[$iArrayKey]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//add profiles not already linked with user
|
//add profiles not already linked with user
|
||||||
foreach ($aProfiles as $iProfileId)
|
foreach ($aProfiles as $iProfileId) {
|
||||||
{
|
$oProfilesSet->AddItem(MetaModel::NewObject('URP_UserProfile', ['profileid' => $iProfileId, 'reason' => $sOrigin]));
|
||||||
$oProfilesSet->AddItem(MetaModel::NewObject('URP_UserProfile', array('profileid' => $iProfileId, 'reason' => $sOrigin)));
|
|
||||||
}
|
}
|
||||||
$oUser->Set('profile_list', $oProfilesSet);
|
$oUser->Set('profile_list', $oProfilesSet);
|
||||||
}
|
}
|
||||||
@@ -154,56 +149,49 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$sVersionShort = Dict::Format('UI:iTopVersion:Short', ITOP_APPLICATION, ITOP_VERSION);
|
$sVersionShort = Dict::Format('UI:iTopVersion:Short', ITOP_APPLICATION, ITOP_VERSION);
|
||||||
$sIconUrl = Utils::GetConfig()->Get('app_icon_url');
|
$sIconUrl = Utils::GetConfig()->Get('app_icon_url');
|
||||||
$sDisplayIcon = Branding::GetLoginLogoAbsoluteUrl();
|
$sDisplayIcon = Branding::GetLoginLogoAbsoluteUrl();
|
||||||
$this->add("<div id=\"login-logo\"><a href=\"".htmlentities($sIconUrl, ENT_QUOTES,
|
$this->add("<div id=\"login-logo\"><a href=\"".htmlentities(
|
||||||
self::PAGES_CHARSET)."\"><img title=\"$sVersionShort\" src=\"$sDisplayIcon\"></a></div>\n");
|
$sIconUrl,
|
||||||
|
ENT_QUOTES,
|
||||||
|
self::PAGES_CHARSET
|
||||||
|
)."\"><img title=\"$sVersionShort\" src=\"$sDisplayIcon\"></a></div>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function DisplayLoginForm($bFailedLogin = false)
|
public function DisplayLoginForm($bFailedLogin = false)
|
||||||
{
|
{
|
||||||
$oTwigContext = new LoginTwigRenderer();
|
$oTwigContext = new LoginTwigRenderer();
|
||||||
$aPostedVars = array_merge(array('login_mode', 'loginop'), $oTwigContext->GetPostedVars());
|
$aPostedVars = array_merge(['login_mode', 'loginop'], $oTwigContext->GetPostedVars());
|
||||||
|
|
||||||
$sMessage = Dict::S('UI:Login:IdentifyYourself');
|
$sMessage = Dict::S('UI:Login:IdentifyYourself');
|
||||||
|
|
||||||
// Error message
|
// Error message
|
||||||
if ($bFailedLogin)
|
if ($bFailedLogin) {
|
||||||
{
|
if (self::$m_sLoginFailedMessage != '') {
|
||||||
if (self::$m_sLoginFailedMessage != '')
|
|
||||||
{
|
|
||||||
$sMessage = self::$m_sLoginFailedMessage;
|
$sMessage = self::$m_sLoginFailedMessage;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sMessage = Dict::S('UI:Login:IncorrectLoginPassword');
|
$sMessage = Dict::S('UI:Login:IncorrectLoginPassword');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep the OTHER parameters posted
|
// Keep the OTHER parameters posted
|
||||||
$aPreviousPostedVars = array();
|
$aPreviousPostedVars = [];
|
||||||
foreach($_POST as $sPostedKey => $postedValue)
|
foreach ($_POST as $sPostedKey => $postedValue) {
|
||||||
{
|
if (!in_array($sPostedKey, $aPostedVars)) {
|
||||||
if (!in_array($sPostedKey, $aPostedVars))
|
if (is_array($postedValue)) {
|
||||||
{
|
foreach ($postedValue as $sKey => $sValue) {
|
||||||
if (is_array($postedValue))
|
|
||||||
{
|
|
||||||
foreach($postedValue as $sKey => $sValue)
|
|
||||||
{
|
|
||||||
$sName = "{$sPostedKey}[{$sKey}]";
|
$sName = "{$sPostedKey}[{$sKey}]";
|
||||||
$aPreviousPostedVars[$sName] = $sValue;
|
$aPreviousPostedVars[$sName] = $sValue;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aPreviousPostedVars[$sPostedKey] = $postedValue;
|
$aPreviousPostedVars[$sPostedKey] = $postedValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$aVars = array(
|
$aVars = [
|
||||||
'bFailedLogin' => $bFailedLogin,
|
'bFailedLogin' => $bFailedLogin,
|
||||||
'sMessage' => $sMessage,
|
'sMessage' => $sMessage,
|
||||||
'aPreviousPostedVars' => $aPreviousPostedVars,
|
'aPreviousPostedVars' => $aPreviousPostedVars,
|
||||||
);
|
];
|
||||||
$aVars = array_merge($aVars, $oTwigContext->GetDefaultVars());
|
$aVars = array_merge($aVars, $oTwigContext->GetDefaultVars());
|
||||||
|
|
||||||
$oTwigContext->Render($this, 'login.html.twig', $aVars);
|
$oTwigContext->Render($this, 'login.html.twig', $aVars);
|
||||||
@@ -226,26 +214,21 @@ class LoginWebPage extends NiceWebPage
|
|||||||
{
|
{
|
||||||
$sAuthUser = utils::ReadParam('auth_user', '', true, 'raw_data');
|
$sAuthUser = utils::ReadParam('auth_user', '', true, 'raw_data');
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
UserRights::Login($sAuthUser); // Set the user's language (if possible!)
|
UserRights::Login($sAuthUser); // Set the user's language (if possible!)
|
||||||
/** @var UserInternal $oUser */
|
/** @var UserInternal $oUser */
|
||||||
$oUser = UserRights::GetUserObject();
|
$oUser = UserRights::GetUserObject();
|
||||||
|
|
||||||
if ($oUser != null)
|
if ($oUser != null) {
|
||||||
{
|
if (!MetaModel::IsValidAttCode(get_class($oUser), 'reset_pwd_token')) {
|
||||||
if (!MetaModel::IsValidAttCode(get_class($oUser), 'reset_pwd_token'))
|
|
||||||
{
|
|
||||||
throw new Exception(Dict::S('UI:ResetPwd-Error-NotPossible'));
|
throw new Exception(Dict::S('UI:ResetPwd-Error-NotPossible'));
|
||||||
}
|
}
|
||||||
if (!$oUser->CanChangePassword())
|
if (!$oUser->CanChangePassword()) {
|
||||||
{
|
|
||||||
throw new Exception(Dict::S('UI:ResetPwd-Error-FixedPwd'));
|
throw new Exception(Dict::S('UI:ResetPwd-Error-FixedPwd'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$sTo = $oUser->GetResetPasswordEmail(); // throws Exceptions if not allowed
|
$sTo = $oUser->GetResetPasswordEmail(); // throws Exceptions if not allowed
|
||||||
if ($sTo == '')
|
if ($sTo == '') {
|
||||||
{
|
|
||||||
throw new Exception(Dict::S('UI:ResetPwd-Error-NoEmail'));
|
throw new Exception(Dict::S('UI:ResetPwd-Error-NoEmail'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,8 +248,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$sResetUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?loginop=reset_pwd&auth_user='.urlencode($oUser->Get('login')).'&token='.urlencode($sToken);
|
$sResetUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?loginop=reset_pwd&auth_user='.urlencode($oUser->Get('login')).'&token='.urlencode($sToken);
|
||||||
$oEmail->SetBody(Dict::Format('UI:ResetPwd-EmailBody', $sResetUrl, $oUser->Get('login')));
|
$oEmail->SetBody(Dict::Format('UI:ResetPwd-EmailBody', $sResetUrl, $oUser->Get('login')));
|
||||||
$iRes = $oEmail->Send($aIssues, true /* force synchronous exec */);
|
$iRes = $oEmail->Send($aIssues, true /* force synchronous exec */);
|
||||||
switch ($iRes)
|
switch ($iRes) {
|
||||||
{
|
|
||||||
//case EMAIL_SEND_PENDING:
|
//case EMAIL_SEND_PENDING:
|
||||||
case EMAIL_SEND_OK:
|
case EMAIL_SEND_OK:
|
||||||
break;
|
break;
|
||||||
@@ -278,13 +260,10 @@ class LoginWebPage extends NiceWebPage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$oTwigContext = new LoginTwigRenderer();
|
$oTwigContext = new LoginTwigRenderer();
|
||||||
$aVars = $oTwigContext->GetDefaultVars();
|
$aVars = $oTwigContext->GetDefaultVars();
|
||||||
$oTwigContext->Render($this, 'forgotpwdsent.html.twig', $aVars);
|
$oTwigContext->Render($this, 'forgotpwdsent.html.twig', $aVars);
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch(Exception $e)
|
|
||||||
{
|
|
||||||
$this->DisplayForgotPwdForm(true, $e->getMessage());
|
$this->DisplayForgotPwdForm(true, $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,22 +283,16 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$aVars['sToken'] = $sToken;
|
$aVars['sToken'] = $sToken;
|
||||||
$aVars['sErrorMessage'] = $sErrorMessage;
|
$aVars['sErrorMessage'] = $sErrorMessage;
|
||||||
|
|
||||||
if (($oUser == null))
|
if (($oUser == null)) {
|
||||||
{
|
|
||||||
$aVars['bNoUser'] = true;
|
$aVars['bNoUser'] = true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aVars['bNoUser'] = false;
|
$aVars['bNoUser'] = false;
|
||||||
$aVars['sUserName'] = $oUser->GetFriendlyName();
|
$aVars['sUserName'] = $oUser->GetFriendlyName();
|
||||||
$oEncryptedToken = $oUser->Get('reset_pwd_token');
|
$oEncryptedToken = $oUser->Get('reset_pwd_token');
|
||||||
|
|
||||||
if (!$oEncryptedToken->CheckPassword($sToken))
|
if (!$oEncryptedToken->CheckPassword($sToken)) {
|
||||||
{
|
|
||||||
$aVars['bBadToken'] = true;
|
$aVars['bBadToken'] = true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aVars['bBadToken'] = false;
|
$aVars['bBadToken'] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -342,21 +315,15 @@ class LoginWebPage extends NiceWebPage
|
|||||||
|
|
||||||
$aVars['sAuthUser'] = $sAuthUser;
|
$aVars['sAuthUser'] = $sAuthUser;
|
||||||
$aVars['sToken'] = $sToken;
|
$aVars['sToken'] = $sToken;
|
||||||
if (($oUser == null))
|
if (($oUser == null)) {
|
||||||
{
|
|
||||||
$aVars['bNoUser'] = true;
|
$aVars['bNoUser'] = true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aVars['bNoUser'] = false;
|
$aVars['bNoUser'] = false;
|
||||||
$oEncryptedToken = $oUser->Get('reset_pwd_token');
|
$oEncryptedToken = $oUser->Get('reset_pwd_token');
|
||||||
|
|
||||||
if (!$oEncryptedToken->CheckPassword($sToken))
|
if (!$oEncryptedToken->CheckPassword($sToken)) {
|
||||||
{
|
|
||||||
$aVars['bBadToken'] = true;
|
$aVars['bBadToken'] = true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aVars['bBadToken'] = false;
|
$aVars['bBadToken'] = false;
|
||||||
// Trash the token and change the password
|
// Trash the token and change the password
|
||||||
$oUser->Set('reset_pwd_token', new ormPassword());
|
$oUser->Set('reset_pwd_token', new ormPassword());
|
||||||
@@ -413,7 +380,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
// Note: This will destroy the session, and not just the session data!
|
// Note: This will destroy the session, and not just the session data!
|
||||||
}
|
}
|
||||||
|
|
||||||
static function SecureConnectionRequired()
|
public static function SecureConnectionRequired()
|
||||||
{
|
{
|
||||||
return MetaModel::GetConfig()->GetSecureConnectionRequired();
|
return MetaModel::GetConfig()->GetSecureConnectionRequired();
|
||||||
}
|
}
|
||||||
@@ -423,7 +390,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
* @param string $sString
|
* @param string $sString
|
||||||
* @return bool True if the string contains some typical UTF-8 multi-byte sequences
|
* @return bool True if the string contains some typical UTF-8 multi-byte sequences
|
||||||
*/
|
*/
|
||||||
static function LooksLikeUTF8($sString)
|
public static function LooksLikeUTF8($sString)
|
||||||
{
|
{
|
||||||
return preg_match('%(?:
|
return preg_match('%(?:
|
||||||
[\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|
[\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|
||||||
@@ -446,22 +413,19 @@ class LoginWebPage extends NiceWebPage
|
|||||||
protected static function Login($iOnExit)
|
protected static function Login($iOnExit)
|
||||||
{
|
{
|
||||||
self::$iOnExit = $iOnExit;
|
self::$iOnExit = $iOnExit;
|
||||||
if (self::SecureConnectionRequired() && !utils::IsConnectionSecure())
|
if (self::SecureConnectionRequired() && !utils::IsConnectionSecure()) {
|
||||||
{
|
|
||||||
// Non secured URL... request for a secure connection
|
// Non secured URL... request for a secure connection
|
||||||
throw new Exception('Secure connection required!');
|
throw new Exception('Secure connection required!');
|
||||||
}
|
}
|
||||||
$bLoginDebug = MetaModel::GetConfig()->Get('login_debug');
|
$bLoginDebug = MetaModel::GetConfig()->Get('login_debug');
|
||||||
|
|
||||||
if (Session::Get('login_state') == self::LOGIN_STATE_ERROR)
|
if (Session::Get('login_state') == self::LOGIN_STATE_ERROR) {
|
||||||
{
|
|
||||||
Session::Set('login_state', self::LOGIN_STATE_START);
|
Session::Set('login_state', self::LOGIN_STATE_START);
|
||||||
}
|
}
|
||||||
$sLoginState = Session::Get('login_state');
|
$sLoginState = Session::Get('login_state');
|
||||||
|
|
||||||
$sSessionLog = '';
|
$sSessionLog = '';
|
||||||
if ($bLoginDebug)
|
if ($bLoginDebug) {
|
||||||
{
|
|
||||||
IssueLog::Info("---------------------------------");
|
IssueLog::Info("---------------------------------");
|
||||||
IssueLog::Info($_SERVER['REQUEST_URI']);
|
IssueLog::Info($_SERVER['REQUEST_URI']);
|
||||||
IssueLog::Info("--> Entering Login FSM with state: [$sLoginState]");
|
IssueLog::Info("--> Entering Login FSM with state: [$sLoginState]");
|
||||||
@@ -472,38 +436,30 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$iErrorCode = self::EXIT_CODE_OK;
|
$iErrorCode = self::EXIT_CODE_OK;
|
||||||
|
|
||||||
// Finite state machine loop
|
// Finite state machine loop
|
||||||
while (true)
|
while (true) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
$aLoginPlugins = self::GetLoginPluginList();
|
$aLoginPlugins = self::GetLoginPluginList();
|
||||||
if (empty($aLoginPlugins))
|
if (empty($aLoginPlugins)) {
|
||||||
{
|
|
||||||
throw new Exception("Missing login classes");
|
throw new Exception("Missing login classes");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var iLoginFSMExtension $oLoginFSMExtensionInstance */
|
/** @var iLoginFSMExtension $oLoginFSMExtensionInstance */
|
||||||
foreach ($aLoginPlugins as $oLoginFSMExtensionInstance)
|
foreach ($aLoginPlugins as $oLoginFSMExtensionInstance) {
|
||||||
{
|
if ($bLoginDebug) {
|
||||||
if ($bLoginDebug)
|
|
||||||
{
|
|
||||||
$sCurrSessionLog = session_id().' '.utils::GetSessionLog();
|
$sCurrSessionLog = session_id().' '.utils::GetSessionLog();
|
||||||
if ($sCurrSessionLog != $sSessionLog)
|
if ($sCurrSessionLog != $sSessionLog) {
|
||||||
{
|
|
||||||
$sSessionLog = $sCurrSessionLog;
|
$sSessionLog = $sCurrSessionLog;
|
||||||
IssueLog::Info("SESSION: $sSessionLog");
|
IssueLog::Info("SESSION: $sSessionLog");
|
||||||
}
|
}
|
||||||
IssueLog::Info("Login: state: [$sLoginState] call: ".get_class($oLoginFSMExtensionInstance));
|
IssueLog::Info("Login: state: [$sLoginState] call: ".get_class($oLoginFSMExtensionInstance));
|
||||||
}
|
}
|
||||||
$iResponse = $oLoginFSMExtensionInstance->LoginAction($sLoginState, $iErrorCode);
|
$iResponse = $oLoginFSMExtensionInstance->LoginAction($sLoginState, $iErrorCode);
|
||||||
if ($iResponse == self::LOGIN_FSM_RETURN)
|
if ($iResponse == self::LOGIN_FSM_RETURN) {
|
||||||
{
|
|
||||||
EventService::FireEvent(new EventData(EVENT_LOGIN, null, ['code' => $iErrorCode, 'state' => $sLoginState]));
|
EventService::FireEvent(new EventData(EVENT_LOGIN, null, ['code' => $iErrorCode, 'state' => $sLoginState]));
|
||||||
Session::WriteClose();
|
Session::WriteClose();
|
||||||
return $iErrorCode; // Asked to exit FSM, generally login OK
|
return $iErrorCode; // Asked to exit FSM, generally login OK
|
||||||
}
|
}
|
||||||
if ($iResponse == self::LOGIN_FSM_ERROR)
|
if ($iResponse == self::LOGIN_FSM_ERROR) {
|
||||||
{
|
|
||||||
EventService::FireEvent(new EventData(EVENT_LOGIN, null, ['code' => $iErrorCode, 'state' => $sLoginState]));
|
EventService::FireEvent(new EventData(EVENT_LOGIN, null, ['code' => $iErrorCode, 'state' => $sLoginState]));
|
||||||
$sLoginState = self::LOGIN_STATE_SET_ERROR; // Next state will be error
|
$sLoginState = self::LOGIN_STATE_SET_ERROR; // Next state will be error
|
||||||
// An error was detected, skip the other plugins turn
|
// An error was detected, skip the other plugins turn
|
||||||
@@ -515,9 +471,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
// Every plugin has nothing else to do in this state, go forward
|
// Every plugin has nothing else to do in this state, go forward
|
||||||
$sLoginState = self::AdvanceLoginFSMState($sLoginState);
|
$sLoginState = self::AdvanceLoginFSMState($sLoginState);
|
||||||
Session::Set('login_state', $sLoginState);
|
Session::Set('login_state', $sLoginState);
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
EventService::FireEvent(new EventData(EVENT_LOGIN, null, ['state' => $_SESSION['login_state']]));
|
EventService::FireEvent(new EventData(EVENT_LOGIN, null, ['state' => $_SESSION['login_state']]));
|
||||||
IssueLog::Error($e->getTraceAsString());
|
IssueLog::Error($e->getTraceAsString());
|
||||||
static::ResetSession();
|
static::ResetSession();
|
||||||
@@ -537,30 +491,23 @@ class LoginWebPage extends NiceWebPage
|
|||||||
*/
|
*/
|
||||||
public static function GetLoginPluginList($sInterface = 'iLoginFSMExtension', $bFilterWithMode = true)
|
public static function GetLoginPluginList($sInterface = 'iLoginFSMExtension', $bFilterWithMode = true)
|
||||||
{
|
{
|
||||||
$aAllPlugins = array();
|
$aAllPlugins = [];
|
||||||
|
|
||||||
if ($bFilterWithMode)
|
if ($bFilterWithMode) {
|
||||||
{
|
|
||||||
$sCurrentLoginMode = Session::Get('login_mode', '');
|
$sCurrentLoginMode = Session::Get('login_mode', '');
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sCurrentLoginMode = '';
|
$sCurrentLoginMode = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var iLoginExtension $oLoginExtensionInstance */
|
/** @var iLoginExtension $oLoginExtensionInstance */
|
||||||
foreach (MetaModel::EnumPlugins($sInterface) as $oLoginExtensionInstance)
|
foreach (MetaModel::EnumPlugins($sInterface) as $oLoginExtensionInstance) {
|
||||||
{
|
|
||||||
$aLoginModes = $oLoginExtensionInstance->ListSupportedLoginModes();
|
$aLoginModes = $oLoginExtensionInstance->ListSupportedLoginModes();
|
||||||
$aLoginModes = (is_array($aLoginModes) ? $aLoginModes : array());
|
$aLoginModes = (is_array($aLoginModes) ? $aLoginModes : []);
|
||||||
foreach ($aLoginModes as $sLoginMode)
|
foreach ($aLoginModes as $sLoginMode) {
|
||||||
{
|
|
||||||
// Keep only the plugins for the current login mode + before + after
|
// Keep only the plugins for the current login mode + before + after
|
||||||
if (empty($sCurrentLoginMode) || ($sLoginMode == $sCurrentLoginMode) || ($sLoginMode == 'before') || ($sLoginMode == 'after'))
|
if (empty($sCurrentLoginMode) || ($sLoginMode == $sCurrentLoginMode) || ($sLoginMode == 'before') || ($sLoginMode == 'after')) {
|
||||||
{
|
if (!isset($aAllPlugins[$sLoginMode])) {
|
||||||
if (!isset($aAllPlugins[$sLoginMode]))
|
$aAllPlugins[$sLoginMode] = [];
|
||||||
{
|
|
||||||
$aAllPlugins[$sLoginMode] = array();
|
|
||||||
}
|
}
|
||||||
$aAllPlugins[$sLoginMode][] = $oLoginExtensionInstance;
|
$aAllPlugins[$sLoginMode][] = $oLoginExtensionInstance;
|
||||||
break; // Stop here to avoid registering a plugin twice
|
break; // Stop here to avoid registering a plugin twice
|
||||||
@@ -569,12 +516,10 @@ class LoginWebPage extends NiceWebPage
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Order and filter by the config list of allowed types (allowed_login_types)
|
// Order and filter by the config list of allowed types (allowed_login_types)
|
||||||
$aAllowedLoginModes = array_merge(array('before'), MetaModel::GetConfig()->GetAllowedLoginTypes(), array('after'));
|
$aAllowedLoginModes = array_merge(['before'], MetaModel::GetConfig()->GetAllowedLoginTypes(), ['after']);
|
||||||
$aPlugins = array();
|
$aPlugins = [];
|
||||||
foreach ($aAllowedLoginModes as $sAllowedMode)
|
foreach ($aAllowedLoginModes as $sAllowedMode) {
|
||||||
{
|
if (isset($aAllPlugins[$sAllowedMode])) {
|
||||||
if (isset($aAllPlugins[$sAllowedMode]))
|
|
||||||
{
|
|
||||||
$aPlugins = array_merge($aPlugins, $aAllPlugins[$sAllowedMode]);
|
$aPlugins = array_merge($aPlugins, $aAllPlugins[$sAllowedMode]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -590,8 +535,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
*/
|
*/
|
||||||
private static function AdvanceLoginFSMState($sLoginState)
|
private static function AdvanceLoginFSMState($sLoginState)
|
||||||
{
|
{
|
||||||
switch ($sLoginState)
|
switch ($sLoginState) {
|
||||||
{
|
|
||||||
case self::LOGIN_STATE_START:
|
case self::LOGIN_STATE_START:
|
||||||
return self::LOGIN_STATE_MODE_DETECTION;
|
return self::LOGIN_STATE_MODE_DETECTION;
|
||||||
|
|
||||||
@@ -638,8 +582,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
public static function CheckUser($sAuthUser, $sAuthPassword = '', $sAuthentication = 'external')
|
public static function CheckUser($sAuthUser, $sAuthPassword = '', $sAuthentication = 'external')
|
||||||
{
|
{
|
||||||
$oUser = self::FindUser($sAuthUser, true, ucfirst(strtolower($sAuthentication)));
|
$oUser = self::FindUser($sAuthUser, true, ucfirst(strtolower($sAuthentication)));
|
||||||
if (is_null($oUser))
|
if (is_null($oUser)) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -668,8 +611,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
{
|
{
|
||||||
// User is Ok, let's save it in the session and proceed with normal login
|
// User is Ok, let's save it in the session and proceed with normal login
|
||||||
$bLoginSuccess = UserRights::Login($sAuthUser, $sAuthentication); // Login & set the user's language
|
$bLoginSuccess = UserRights::Login($sAuthUser, $sAuthentication); // Login & set the user's language
|
||||||
if (!$bLoginSuccess)
|
if (!$bLoginSuccess) {
|
||||||
{
|
|
||||||
throw new Exception("Bad user");
|
throw new Exception("Bad user");
|
||||||
}
|
}
|
||||||
if (MetaModel::GetConfig()->Get('log_usage')) {
|
if (MetaModel::GetConfig()->Get('log_usage')) {
|
||||||
@@ -696,12 +638,10 @@ class LoginWebPage extends NiceWebPage
|
|||||||
*/
|
*/
|
||||||
public static function CheckLoggedUser(&$iErrorCode)
|
public static function CheckLoggedUser(&$iErrorCode)
|
||||||
{
|
{
|
||||||
if (Session::IsSet('auth_user'))
|
if (Session::IsSet('auth_user')) {
|
||||||
{
|
|
||||||
// Already authenticated
|
// Already authenticated
|
||||||
$bRet = UserRights::Login(Session::Get('auth_user')); // Login & set the user's language
|
$bRet = UserRights::Login(Session::Get('auth_user')); // Login & set the user's language
|
||||||
if ($bRet)
|
if ($bRet) {
|
||||||
{
|
|
||||||
$iErrorCode = self::EXIT_CODE_OK;
|
$iErrorCode = self::EXIT_CODE_OK;
|
||||||
return self::LOGIN_FSM_RETURN;
|
return self::LOGIN_FSM_RETURN;
|
||||||
}
|
}
|
||||||
@@ -727,8 +667,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
|
|
||||||
public static function SetLoginModeAndReload($sNewLoginMode)
|
public static function SetLoginModeAndReload($sNewLoginMode)
|
||||||
{
|
{
|
||||||
if (Session::Get('login_mode') == $sNewLoginMode)
|
if (Session::Get('login_mode') == $sNewLoginMode) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Session::Set('login_mode', $sNewLoginMode);
|
Session::Set('login_mode', $sNewLoginMode);
|
||||||
@@ -738,8 +677,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
public static function HTTPReload()
|
public static function HTTPReload()
|
||||||
{
|
{
|
||||||
$sOriginURL = utils::GetCurrentAbsoluteUrl();
|
$sOriginURL = utils::GetCurrentAbsoluteUrl();
|
||||||
if (!utils::StartsWith($sOriginURL, utils::GetAbsoluteUrlAppRoot()))
|
if (!utils::StartsWith($sOriginURL, utils::GetAbsoluteUrlAppRoot())) {
|
||||||
{
|
|
||||||
// If the found URL does not start with the configured AppRoot URL
|
// If the found URL does not start with the configured AppRoot URL
|
||||||
$sOriginURL = utils::GetAbsoluteUrlAppRoot().'pages/UI.php';
|
$sOriginURL = utils::GetAbsoluteUrlAppRoot().'pages/UI.php';
|
||||||
}
|
}
|
||||||
@@ -753,7 +691,6 @@ class LoginWebPage extends NiceWebPage
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provisioning API: Find a User
|
* Provisioning API: Find a User
|
||||||
*
|
*
|
||||||
@@ -767,33 +704,28 @@ class LoginWebPage extends NiceWebPage
|
|||||||
*/
|
*/
|
||||||
public static function FindUser($sAuthUser, $bMustBeValid = true, $sType = 'External')
|
public static function FindUser($sAuthUser, $bMustBeValid = true, $sType = 'External')
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
$aArgs = ['login' => $sAuthUser];
|
||||||
$aArgs = array('login' => $sAuthUser);
|
|
||||||
$sUserClass = "User$sType";
|
$sUserClass = "User$sType";
|
||||||
$oSearch = DBObjectSearch::FromOQL("SELECT $sUserClass WHERE login = :login");
|
$oSearch = DBObjectSearch::FromOQL("SELECT $sUserClass WHERE login = :login");
|
||||||
if ($bMustBeValid)
|
if ($bMustBeValid) {
|
||||||
{
|
|
||||||
$oSearch->AddCondition('status', 'enabled');
|
$oSearch->AddCondition('status', 'enabled');
|
||||||
}
|
}
|
||||||
$oSet = new DBObjectSet($oSearch, array(), $aArgs);
|
$oSet = new DBObjectSet($oSearch, [], $aArgs);
|
||||||
if ($oSet->CountExceeds(0))
|
if ($oSet->CountExceeds(0)) {
|
||||||
{
|
|
||||||
/** @var User $oUser */
|
/** @var User $oUser */
|
||||||
$oUser = $oSet->Fetch();
|
$oUser = $oSet->Fetch();
|
||||||
|
|
||||||
return $oUser;
|
return $oUser;
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
IssueLog::Error($e->getMessage());
|
IssueLog::Error($e->getMessage());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provisioning API: Find a Person by email
|
* Provisioning API: Find a Person by email
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*
|
*
|
||||||
@@ -805,19 +737,15 @@ class LoginWebPage extends NiceWebPage
|
|||||||
{
|
{
|
||||||
/** @var \Person $oPerson */
|
/** @var \Person $oPerson */
|
||||||
$oPerson = null;
|
$oPerson = null;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
$oSearch = new DBObjectSearch('Person');
|
$oSearch = new DBObjectSearch('Person');
|
||||||
$oSearch->AddCondition('email', $sEmail);
|
$oSearch->AddCondition('email', $sEmail);
|
||||||
$oSet = new DBObjectSet($oSearch);
|
$oSet = new DBObjectSet($oSearch);
|
||||||
if ($oSet->CountExceeds(1))
|
if ($oSet->CountExceeds(1)) {
|
||||||
{
|
|
||||||
throw new Exception(Dict::S('UI:Login:Error:MultipleContactsHaveSameEmail'));
|
throw new Exception(Dict::S('UI:Login:Error:MultipleContactsHaveSameEmail'));
|
||||||
}
|
}
|
||||||
$oPerson = $oSet->Fetch();
|
$oPerson = $oSet->Fetch();
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
IssueLog::Error($e->getMessage());
|
IssueLog::Error($e->getMessage());
|
||||||
}
|
}
|
||||||
return $oPerson;
|
return $oPerson;
|
||||||
@@ -836,16 +764,14 @@ class LoginWebPage extends NiceWebPage
|
|||||||
*
|
*
|
||||||
* @return \Person
|
* @return \Person
|
||||||
*/
|
*/
|
||||||
public static function ProvisionPerson($sFirstName, $sLastName, $sEmail, $sOrganization, $aAdditionalParams = array())
|
public static function ProvisionPerson($sFirstName, $sLastName, $sEmail, $sOrganization, $aAdditionalParams = [])
|
||||||
{
|
{
|
||||||
/** @var Person $oPerson */
|
/** @var Person $oPerson */
|
||||||
$oPerson = null;
|
$oPerson = null;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
CMDBObject::SetTrackOrigin('custom-extension');
|
CMDBObject::SetTrackOrigin('custom-extension');
|
||||||
$sInfo = 'External User provisioning';
|
$sInfo = 'External User provisioning';
|
||||||
if (Session::IsSet('login_mode'))
|
if (Session::IsSet('login_mode')) {
|
||||||
{
|
|
||||||
$sInfo .= " (".Session::Get('login_mode').")";
|
$sInfo .= " (".Session::Get('login_mode').")";
|
||||||
}
|
}
|
||||||
CMDBObject::SetTrackInfo($sInfo);
|
CMDBObject::SetTrackInfo($sInfo);
|
||||||
@@ -855,19 +781,15 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$oPerson->Set('name', $sLastName);
|
$oPerson->Set('name', $sLastName);
|
||||||
$oPerson->Set('email', $sEmail);
|
$oPerson->Set('email', $sEmail);
|
||||||
$oOrg = MetaModel::GetObjectByName('Organization', $sOrganization, false);
|
$oOrg = MetaModel::GetObjectByName('Organization', $sOrganization, false);
|
||||||
if (is_null($oOrg))
|
if (is_null($oOrg)) {
|
||||||
{
|
|
||||||
throw new Exception(Dict::S('UI:Login:Error:WrongOrganizationName'));
|
throw new Exception(Dict::S('UI:Login:Error:WrongOrganizationName'));
|
||||||
}
|
}
|
||||||
$oPerson->Set('org_id', $oOrg->GetKey());
|
$oPerson->Set('org_id', $oOrg->GetKey());
|
||||||
foreach ($aAdditionalParams as $sAttCode => $sValue)
|
foreach ($aAdditionalParams as $sAttCode => $sValue) {
|
||||||
{
|
|
||||||
$oPerson->Set($sAttCode, $sValue);
|
$oPerson->Set($sAttCode, $sValue);
|
||||||
}
|
}
|
||||||
$oPerson->DBInsert();
|
$oPerson->DBInsert();
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
IssueLog::Error($e->getMessage());
|
IssueLog::Error($e->getMessage());
|
||||||
}
|
}
|
||||||
return $oPerson;
|
return $oPerson;
|
||||||
@@ -886,27 +808,23 @@ class LoginWebPage extends NiceWebPage
|
|||||||
*/
|
*/
|
||||||
public static function ProvisionUser($sAuthUser, $oPerson, $aRequestedProfiles)
|
public static function ProvisionUser($sAuthUser, $oPerson, $aRequestedProfiles)
|
||||||
{
|
{
|
||||||
if (!MetaModel::IsValidClass('URP_Profiles'))
|
if (!MetaModel::IsValidClass('URP_Profiles')) {
|
||||||
{
|
|
||||||
IssueLog::Error("URP_Profiles is not a valid class. Automatic creation of Users is not supported in this context, sorry.");
|
IssueLog::Error("URP_Profiles is not a valid class. Automatic creation of Users is not supported in this context, sorry.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var UserExternal $oUser */
|
/** @var UserExternal $oUser */
|
||||||
$oUser = null;
|
$oUser = null;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
CMDBObject::SetTrackOrigin('custom-extension');
|
CMDBObject::SetTrackOrigin('custom-extension');
|
||||||
$sInfo = 'External User provisioning';
|
$sInfo = 'External User provisioning';
|
||||||
if (Session::IsSet('login_mode'))
|
if (Session::IsSet('login_mode')) {
|
||||||
{
|
|
||||||
$sInfo .= " (".Session::Get('login_mode').")";
|
$sInfo .= " (".Session::Get('login_mode').")";
|
||||||
}
|
}
|
||||||
CMDBObject::SetTrackInfo($sInfo);
|
CMDBObject::SetTrackInfo($sInfo);
|
||||||
|
|
||||||
$oUser = MetaModel::GetObjectByName('UserExternal', $sAuthUser, false);
|
$oUser = MetaModel::GetObjectByName('UserExternal', $sAuthUser, false);
|
||||||
if (is_null($oUser))
|
if (is_null($oUser)) {
|
||||||
{
|
|
||||||
$oUser = MetaModel::NewObject('UserExternal');
|
$oUser = MetaModel::NewObject('UserExternal');
|
||||||
$oUser->Set('login', $sAuthUser);
|
$oUser->Set('login', $sAuthUser);
|
||||||
$oUser->Set('contactid', $oPerson->GetKey());
|
$oUser->Set('contactid', $oPerson->GetKey());
|
||||||
@@ -916,41 +834,33 @@ class LoginWebPage extends NiceWebPage
|
|||||||
// read all the existing profiles
|
// read all the existing profiles
|
||||||
$oProfilesSearch = new DBObjectSearch('URP_Profiles');
|
$oProfilesSearch = new DBObjectSearch('URP_Profiles');
|
||||||
$oProfilesSet = new DBObjectSet($oProfilesSearch);
|
$oProfilesSet = new DBObjectSet($oProfilesSearch);
|
||||||
$aAllProfiles = array();
|
$aAllProfiles = [];
|
||||||
while ($oProfile = $oProfilesSet->Fetch())
|
while ($oProfile = $oProfilesSet->Fetch()) {
|
||||||
{
|
|
||||||
$aAllProfiles[mb_strtolower($oProfile->GetName())] = $oProfile->GetKey();
|
$aAllProfiles[mb_strtolower($oProfile->GetName())] = $oProfile->GetKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
$aProfiles = array();
|
$aProfiles = [];
|
||||||
foreach ($aRequestedProfiles as $sRequestedProfile)
|
foreach ($aRequestedProfiles as $sRequestedProfile) {
|
||||||
{
|
|
||||||
$sRequestedProfile = mb_strtolower($sRequestedProfile);
|
$sRequestedProfile = mb_strtolower($sRequestedProfile);
|
||||||
if (isset($aAllProfiles[$sRequestedProfile]))
|
if (isset($aAllProfiles[$sRequestedProfile])) {
|
||||||
{
|
|
||||||
$aProfiles[] = $aAllProfiles[$sRequestedProfile];
|
$aProfiles[] = $aAllProfiles[$sRequestedProfile];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($aProfiles))
|
if (empty($aProfiles)) {
|
||||||
{
|
|
||||||
throw new Exception(Dict::S('UI:Login:Error:NoValidProfiles'));
|
throw new Exception(Dict::S('UI:Login:Error:NoValidProfiles'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now synchronize the profiles
|
// Now synchronize the profiles
|
||||||
$sOrigin = 'External User provisioning';
|
$sOrigin = 'External User provisioning';
|
||||||
if (Session::IsSet('login_mode'))
|
if (Session::IsSet('login_mode')) {
|
||||||
{
|
|
||||||
$sOrigin .= " (".Session::Get('login_mode').")";
|
$sOrigin .= " (".Session::Get('login_mode').")";
|
||||||
}
|
}
|
||||||
$aExistingProfiles = self::SynchronizeProfiles($oUser, $aProfiles, $sOrigin);
|
$aExistingProfiles = self::SynchronizeProfiles($oUser, $aProfiles, $sOrigin);
|
||||||
if ($oUser->IsModified())
|
if ($oUser->IsModified()) {
|
||||||
{
|
|
||||||
$oUser->DBWrite();
|
$oUser->DBWrite();
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
IssueLog::Error($e->getMessage());
|
IssueLog::Error($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -961,26 +871,18 @@ class LoginWebPage extends NiceWebPage
|
|||||||
* Overridable: depending on the user, head toward a dedicated portal
|
* Overridable: depending on the user, head toward a dedicated portal
|
||||||
* @param string|null $sRequestedPortalId
|
* @param string|null $sRequestedPortalId
|
||||||
* @param int $iOnExit How to complete the call: redirect or return a code
|
* @param int $iOnExit How to complete the call: redirect or return a code
|
||||||
*/
|
*/
|
||||||
protected static function ChangeLocation($sRequestedPortalId = null, $iOnExit = self::EXIT_PROMPT)
|
protected static function ChangeLocation($sRequestedPortalId = null, $iOnExit = self::EXIT_PROMPT)
|
||||||
{
|
{
|
||||||
$ret = call_user_func(array(self::$sHandlerClass, 'Dispatch'), $sRequestedPortalId);
|
$ret = call_user_func([self::$sHandlerClass, 'Dispatch'], $sRequestedPortalId);
|
||||||
if ($ret === true)
|
if ($ret === true) {
|
||||||
{
|
|
||||||
return self::EXIT_CODE_OK;
|
return self::EXIT_CODE_OK;
|
||||||
}
|
} elseif ($ret === false) {
|
||||||
else if($ret === false)
|
|
||||||
{
|
|
||||||
throw new Exception('Nowhere to go: Your combination of user Profiles denies you access to any '.ITOP_APPLICATION_SHORT.' portal. Please contact your administrator');
|
throw new Exception('Nowhere to go: Your combination of user Profiles denies you access to any '.ITOP_APPLICATION_SHORT.' portal. Please contact your administrator');
|
||||||
}
|
} else {
|
||||||
else
|
if ($iOnExit == self::EXIT_RETURN) {
|
||||||
{
|
|
||||||
if ($iOnExit == self::EXIT_RETURN)
|
|
||||||
{
|
|
||||||
return self::EXIT_CODE_PORTALUSERNOTAUTHORIZED;
|
return self::EXIT_CODE_PORTALUSERNOTAUTHORIZED;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// No rights to be here, redirect to the portal
|
// No rights to be here, redirect to the portal
|
||||||
header('Location: '.$ret);
|
header('Location: '.$ret);
|
||||||
die();
|
die();
|
||||||
@@ -1002,7 +904,7 @@ class LoginWebPage extends NiceWebPage
|
|||||||
* @return int|mixed|string
|
* @return int|mixed|string
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
static function DoLogin($bMustBeAdmin = false, $bIsAllowedToPortalUsers = false, $iOnExit = self::EXIT_PROMPT)
|
public static function DoLogin($bMustBeAdmin = false, $bIsAllowedToPortalUsers = false, $iOnExit = self::EXIT_PROMPT)
|
||||||
{
|
{
|
||||||
$sRequestedPortalId = $bIsAllowedToPortalUsers ? 'legacy_portal' : 'backoffice';
|
$sRequestedPortalId = $bIsAllowedToPortalUsers ? 'legacy_portal' : 'backoffice';
|
||||||
return self::DoLoginEx($sRequestedPortalId, $bMustBeAdmin, $iOnExit);
|
return self::DoLoginEx($sRequestedPortalId, $bMustBeAdmin, $iOnExit);
|
||||||
@@ -1019,23 +921,18 @@ class LoginWebPage extends NiceWebPage
|
|||||||
* @return int|mixed|string
|
* @return int|mixed|string
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
static function DoLoginEx($sRequestedPortalId = null, $bMustBeAdmin = false, $iOnExit = self::EXIT_PROMPT)
|
public static function DoLoginEx($sRequestedPortalId = null, $bMustBeAdmin = false, $iOnExit = self::EXIT_PROMPT)
|
||||||
{
|
{
|
||||||
$operation = utils::ReadParam('loginop', '');
|
$operation = utils::ReadParam('loginop', '');
|
||||||
|
|
||||||
$sMessage = self::HandleOperations($operation); // May exit directly
|
$sMessage = self::HandleOperations($operation); // May exit directly
|
||||||
|
|
||||||
$iRet = self::Login($iOnExit);
|
$iRet = self::Login($iOnExit);
|
||||||
if ($iRet == self::EXIT_CODE_OK)
|
if ($iRet == self::EXIT_CODE_OK) {
|
||||||
{
|
if ($bMustBeAdmin && !UserRights::IsAdministrator()) {
|
||||||
if ($bMustBeAdmin && !UserRights::IsAdministrator())
|
if ($iOnExit == self::EXIT_RETURN) {
|
||||||
{
|
|
||||||
if ($iOnExit == self::EXIT_RETURN)
|
|
||||||
{
|
|
||||||
return self::EXIT_CODE_MUSTBEADMIN;
|
return self::EXIT_CODE_MUSTBEADMIN;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||||
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
||||||
$oP->add("<h1>".Dict::S('UI:Login:Error:AccessAdmin')."</h1>\n");
|
$oP->add("<h1>".Dict::S('UI:Login:Error:AccessAdmin')."</h1>\n");
|
||||||
@@ -1044,69 +941,52 @@ class LoginWebPage extends NiceWebPage
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$iRet = call_user_func(array(self::$sHandlerClass, 'ChangeLocation'), $sRequestedPortalId, $iOnExit);
|
$iRet = call_user_func([self::$sHandlerClass, 'ChangeLocation'], $sRequestedPortalId, $iOnExit);
|
||||||
}
|
}
|
||||||
if ($iOnExit == self::EXIT_RETURN)
|
if ($iOnExit == self::EXIT_RETURN) {
|
||||||
{
|
|
||||||
return $iRet;
|
return $iRet;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return $sMessage;
|
return $sMessage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected static function HandleOperations($operation)
|
protected static function HandleOperations($operation)
|
||||||
{
|
{
|
||||||
$sMessage = ''; // most of the operations never return, but some can return a message to be displayed
|
$sMessage = ''; // most of the operations never return, but some can return a message to be displayed
|
||||||
if ($operation == 'logoff')
|
if ($operation == 'logoff') {
|
||||||
{
|
|
||||||
self::ResetSession();
|
self::ResetSession();
|
||||||
$oPage = self::NewLoginWebPage();
|
$oPage = self::NewLoginWebPage();
|
||||||
$oPage->DisplayLoginForm(false /* not a failed attempt */);
|
$oPage->DisplayLoginForm(false /* not a failed attempt */);
|
||||||
$oPage->output();
|
$oPage->output();
|
||||||
exit;
|
exit;
|
||||||
}
|
} elseif ($operation == 'forgot_pwd') {
|
||||||
else if ($operation == 'forgot_pwd')
|
|
||||||
{
|
|
||||||
$oPage = self::NewLoginWebPage();
|
$oPage = self::NewLoginWebPage();
|
||||||
$oPage->DisplayForgotPwdForm();
|
$oPage->DisplayForgotPwdForm();
|
||||||
$oPage->output();
|
$oPage->output();
|
||||||
exit;
|
exit;
|
||||||
}
|
} elseif ($operation == 'forgot_pwd_go') {
|
||||||
else if ($operation == 'forgot_pwd_go')
|
|
||||||
{
|
|
||||||
$oPage = self::NewLoginWebPage();
|
$oPage = self::NewLoginWebPage();
|
||||||
$oPage->ForgotPwdGo();
|
$oPage->ForgotPwdGo();
|
||||||
$oPage->output();
|
$oPage->output();
|
||||||
exit;
|
exit;
|
||||||
}
|
} elseif ($operation == 'reset_pwd') {
|
||||||
else if ($operation == 'reset_pwd')
|
|
||||||
{
|
|
||||||
$oPage = self::NewLoginWebPage();
|
$oPage = self::NewLoginWebPage();
|
||||||
$oPage->DisplayResetPwdForm();
|
$oPage->DisplayResetPwdForm();
|
||||||
$oPage->output();
|
$oPage->output();
|
||||||
exit;
|
exit;
|
||||||
}
|
} elseif ($operation == 'do_reset_pwd') {
|
||||||
else if ($operation == 'do_reset_pwd')
|
|
||||||
{
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$oPage = self::NewLoginWebPage();
|
$oPage = self::NewLoginWebPage();
|
||||||
$oPage->DoResetPassword();
|
$oPage->DoResetPassword();
|
||||||
}
|
} catch (CoreCannotSaveObjectException $e) {
|
||||||
catch (CoreCannotSaveObjectException $e)
|
|
||||||
{
|
|
||||||
$oPage = self::NewLoginWebPage();
|
$oPage = self::NewLoginWebPage();
|
||||||
$oPage->DisplayResetPwdForm($e->getIssue());
|
$oPage->DisplayResetPwdForm($e->getIssue());
|
||||||
}
|
}
|
||||||
|
|
||||||
$oPage->output();
|
$oPage->output();
|
||||||
exit;
|
exit;
|
||||||
}
|
} elseif ($operation == 'change_pwd') {
|
||||||
else if ($operation == 'change_pwd')
|
if (Session::IsSet('auth_user')) {
|
||||||
{
|
|
||||||
if (Session::IsSet('auth_user'))
|
|
||||||
{
|
|
||||||
$sAuthUser = Session::Get('auth_user');
|
$sAuthUser = Session::Get('auth_user');
|
||||||
$sIssue = Session::Get('pwd_issue');
|
$sIssue = Session::Get('pwd_issue');
|
||||||
Session::Unset('pwd_issue');
|
Session::Unset('pwd_issue');
|
||||||
@@ -1118,16 +998,13 @@ class LoginWebPage extends NiceWebPage
|
|||||||
$oPage->output();
|
$oPage->output();
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
} elseif ($operation == 'check_pwd_policy') {
|
||||||
else if ($operation == 'check_pwd_policy')
|
|
||||||
{
|
|
||||||
$sAuthUser = Session::Get('auth_user');
|
$sAuthUser = Session::Get('auth_user');
|
||||||
UserRights::Login($sAuthUser); // Set the user's language
|
UserRights::Login($sAuthUser); // Set the user's language
|
||||||
|
|
||||||
$aPwdMap = array();
|
$aPwdMap = [];
|
||||||
|
|
||||||
foreach (array('new_pwd', 'retype_new_pwd') as $postedPwd)
|
foreach (['new_pwd', 'retype_new_pwd'] as $postedPwd) {
|
||||||
{
|
|
||||||
$oUser = new UserLocal();
|
$oUser = new UserLocal();
|
||||||
$oUser->ValidatePassword($_POST[$postedPwd]);
|
$oUser->ValidatePassword($_POST[$postedPwd]);
|
||||||
|
|
||||||
@@ -1137,27 +1014,21 @@ class LoginWebPage extends NiceWebPage
|
|||||||
echo json_encode($aPwdMap);
|
echo json_encode($aPwdMap);
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
if ($operation == 'do_change_pwd')
|
if ($operation == 'do_change_pwd') {
|
||||||
{
|
if (Session::IsSet('auth_user')) {
|
||||||
if (Session::IsSet('auth_user'))
|
|
||||||
{
|
|
||||||
$sAuthUser = Session::Get('auth_user');
|
$sAuthUser = Session::Get('auth_user');
|
||||||
UserRights::Login($sAuthUser); // Set the user's language
|
UserRights::Login($sAuthUser); // Set the user's language
|
||||||
$sOldPwd = utils::ReadPostedParam('old_pwd', '', 'raw_data');
|
$sOldPwd = utils::ReadPostedParam('old_pwd', '', 'raw_data');
|
||||||
$sNewPwd = utils::ReadPostedParam('new_pwd', '', 'raw_data');
|
$sNewPwd = utils::ReadPostedParam('new_pwd', '', 'raw_data');
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
if (UserRights::CanChangePassword() && ((!UserRights::CheckCredentials($sAuthUser, $sOldPwd)) || (!UserRights::ChangePassword($sOldPwd, $sNewPwd)))) {
|
||||||
if (UserRights::CanChangePassword() && ((!UserRights::CheckCredentials($sAuthUser, $sOldPwd)) || (!UserRights::ChangePassword($sOldPwd, $sNewPwd))))
|
|
||||||
{
|
|
||||||
$oPage = self::NewLoginWebPage();
|
$oPage = self::NewLoginWebPage();
|
||||||
$oPage->DisplayChangePwdForm(true); // old pwd was wrong
|
$oPage->DisplayChangePwdForm(true); // old pwd was wrong
|
||||||
$oPage->output();
|
$oPage->output();
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
} catch (CoreCannotSaveObjectException $e) {
|
||||||
catch (CoreCannotSaveObjectException $e)
|
|
||||||
{
|
|
||||||
$oPage = self::NewLoginWebPage();
|
$oPage = self::NewLoginWebPage();
|
||||||
$oPage->DisplayChangePwdForm(true, $e->getIssue()); // password policy was not met.
|
$oPage->DisplayChangePwdForm(true, $e->getIssue()); // password policy was not met.
|
||||||
$oPage->output();
|
$oPage->output();
|
||||||
@@ -1168,26 +1039,27 @@ class LoginWebPage extends NiceWebPage
|
|||||||
}
|
}
|
||||||
return $sMessage;
|
return $sMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function Dispatch($sRequestedPortalId)
|
protected static function Dispatch($sRequestedPortalId)
|
||||||
{
|
{
|
||||||
if ($sRequestedPortalId === null) return true; // allowed to any portal => return true
|
if ($sRequestedPortalId === null) {
|
||||||
|
return true;
|
||||||
|
} // allowed to any portal => return true
|
||||||
|
|
||||||
$aPortalsConf = PortalDispatcherData::GetData();
|
$aPortalsConf = PortalDispatcherData::GetData();
|
||||||
$aDispatchers = array();
|
$aDispatchers = [];
|
||||||
foreach($aPortalsConf as $sPortalId => $aConf)
|
foreach ($aPortalsConf as $sPortalId => $aConf) {
|
||||||
{
|
|
||||||
$sHandlerClass = $aConf['handler'];
|
$sHandlerClass = $aConf['handler'];
|
||||||
$aDispatchers[$sPortalId] = new $sHandlerClass($sPortalId);
|
$aDispatchers[$sPortalId] = new $sHandlerClass($sPortalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists($sRequestedPortalId, $aDispatchers) && $aDispatchers[$sRequestedPortalId]->IsUserAllowed())
|
if (array_key_exists($sRequestedPortalId, $aDispatchers) && $aDispatchers[$sRequestedPortalId]->IsUserAllowed()) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
foreach($aDispatchers as $sPortalId => $oDispatcher)
|
foreach ($aDispatchers as $sPortalId => $oDispatcher) {
|
||||||
{
|
if ($oDispatcher->IsUserAllowed()) {
|
||||||
if ($oDispatcher->IsUserAllowed()) return $oDispatcher->GetUrl();
|
return $oDispatcher->GetUrl();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false; // nothing matched !!
|
return false; // nothing matched !!
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2024 Combodo SAS
|
* Copyright (C) 2013-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
@@ -17,7 +18,6 @@
|
|||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Maintenance message display functions
|
// Maintenance message display functions
|
||||||
// Only included by approot.inc.php
|
// Only included by approot.inc.php
|
||||||
@@ -33,21 +33,17 @@ function _MaintenanceSetupPageMessage($sTitle, $sMessage)
|
|||||||
{
|
{
|
||||||
// Web Page
|
// Web Page
|
||||||
@include_once(APPROOT.'setup/setuppage.class.inc.php');
|
@include_once(APPROOT.'setup/setuppage.class.inc.php');
|
||||||
if (class_exists('SetupPage'))
|
if (class_exists('SetupPage')) {
|
||||||
{
|
|
||||||
$oP = new ErrorPage($sTitle);
|
$oP = new ErrorPage($sTitle);
|
||||||
$oP->p("<h2 class=\"center\">$sMessage</h2>");
|
$oP->p("<h2 class=\"center\">$sMessage</h2>");
|
||||||
$oP->add_ready_script(
|
$oP->add_ready_script(
|
||||||
<<<JS
|
<<<JS
|
||||||
// Reload in 30s to check if maintenance is over
|
// Reload in 30s to check if maintenance is over
|
||||||
setTimeout(function(){ window.location.reload(); }, 30000);
|
setTimeout(function(){ window.location.reload(); }, 30000);
|
||||||
JS
|
JS
|
||||||
|
|
||||||
);
|
);
|
||||||
$oP->output();
|
$oP->output();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
_MaintenanceTextMessage($sMessage);
|
_MaintenanceTextMessage($sMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,14 +74,13 @@ function _MaintenanceHtmlMessage($sMessage)
|
|||||||
*/
|
*/
|
||||||
function _MaintenanceJsonMessage($sTitle, $sMessage)
|
function _MaintenanceJsonMessage($sTitle, $sMessage)
|
||||||
{
|
{
|
||||||
if (class_exists('JsonPage'))
|
if (class_exists('JsonPage')) {
|
||||||
{
|
|
||||||
$oP = new JsonPage($sTitle);
|
$oP = new JsonPage($sTitle);
|
||||||
$oP->add_header('Access-Control-Allow-Origin: *');
|
$oP->add_header('Access-Control-Allow-Origin: *');
|
||||||
|
|
||||||
$aMessage = [
|
$aMessage = [
|
||||||
'code' => 100,
|
'code' => 100,
|
||||||
'message' =>$sMessage
|
'message' => $sMessage,
|
||||||
];
|
];
|
||||||
|
|
||||||
$oP->AddData($aMessage);
|
$oP->AddData($aMessage);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -13,7 +14,6 @@ require_once(APPROOT.'/application/utils.inc.php');
|
|||||||
require_once(APPROOT.'/application/template.class.inc.php');
|
require_once(APPROOT.'/application/template.class.inc.php');
|
||||||
require_once(APPROOT."/application/user.dashboard.class.inc.php");
|
require_once(APPROOT."/application/user.dashboard.class.inc.php");
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class manipulates, stores and displays the navigation menu used in the application
|
* This class manipulates, stores and displays the navigation menu used in the application
|
||||||
* In order to improve the modularity of the data model and to ease the update/migration
|
* In order to improve the modularity of the data model and to ease the update/migration
|
||||||
@@ -52,43 +52,40 @@ class ApplicationMenu
|
|||||||
/**
|
/**
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
static $bAdditionalMenusLoaded = false;
|
public static $bAdditionalMenusLoaded = false;
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
static $aRootMenus = array();
|
public static $aRootMenus = [];
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
static $aMenusIndex = array();
|
public static $aMenusIndex = [];
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
static $aMenusById = [];
|
public static $aMenusById = [];
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
static $sFavoriteSiloQuery = 'SELECT Organization';
|
public static $sFavoriteSiloQuery = 'SELECT Organization';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function LoadAdditionalMenus()
|
public static function LoadAdditionalMenus()
|
||||||
{
|
{
|
||||||
if (!self::$bAdditionalMenusLoaded)
|
if (!self::$bAdditionalMenusLoaded) {
|
||||||
{
|
|
||||||
// Build menus from module handlers
|
// Build menus from module handlers
|
||||||
//
|
//
|
||||||
/** @var \ModuleHandlerApiInterface $oPHPClass */
|
/** @var \ModuleHandlerApiInterface $oPHPClass */
|
||||||
foreach(MetaModel::EnumPlugins('ModuleHandlerApiInterface') as $oPHPClass)
|
foreach (MetaModel::EnumPlugins('ModuleHandlerApiInterface') as $oPHPClass) {
|
||||||
{
|
$oPHPClass::OnMenuCreation();
|
||||||
$oPHPClass::OnMenuCreation();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Build menus from the menus themselves (e.g. the ShortcutContainerMenuNode will do that)
|
// Build menus from the menus themselves (e.g. the ShortcutContainerMenuNode will do that)
|
||||||
//
|
//
|
||||||
foreach(self::$aRootMenus as $aMenu)
|
foreach (self::$aRootMenus as $aMenu) {
|
||||||
{
|
|
||||||
$oMenuNode = self::GetMenuNode($aMenu['index']);
|
$oMenuNode = self::GetMenuNode($aMenu['index']);
|
||||||
$oMenuNode->PopulateChildMenus();
|
$oMenuNode->PopulateChildMenus();
|
||||||
}
|
}
|
||||||
@@ -125,8 +122,7 @@ class ApplicationMenu
|
|||||||
*/
|
*/
|
||||||
public static function CheckMenuIdEnabled($sMenuId)
|
public static function CheckMenuIdEnabled($sMenuId)
|
||||||
{
|
{
|
||||||
if (self::IsMenuIdEnabled($sMenuId) === false)
|
if (self::IsMenuIdEnabled($sMenuId) === false) {
|
||||||
{
|
|
||||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||||
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
||||||
$oP->add("<h1>".Dict::S('UI:Login:Error:AccessRestricted')."</h1>\n");
|
$oP->add("<h1>".Dict::S('UI:Login:Error:AccessRestricted')."</h1>\n");
|
||||||
@@ -142,7 +138,7 @@ class ApplicationMenu
|
|||||||
* @return bool true if the menu exists and current user is allowed to see the menu
|
* @return bool true if the menu exists and current user is allowed to see the menu
|
||||||
* @since 3.2.0
|
* @since 3.2.0
|
||||||
*/
|
*/
|
||||||
public static function IsMenuIdEnabled($sMenuId):bool
|
public static function IsMenuIdEnabled($sMenuId): bool
|
||||||
{
|
{
|
||||||
self::LoadAdditionalMenus();
|
self::LoadAdditionalMenus();
|
||||||
$oMenuNode = self::GetMenuNode(self::GetMenuIndexById($sMenuId));
|
$oMenuNode = self::GetMenuNode(self::GetMenuIndexById($sMenuId));
|
||||||
@@ -160,22 +156,18 @@ class ApplicationMenu
|
|||||||
public static function InsertMenu(MenuNode $oMenuNode, $iParentIndex, $fRank)
|
public static function InsertMenu(MenuNode $oMenuNode, $iParentIndex, $fRank)
|
||||||
{
|
{
|
||||||
$index = self::GetMenuIndexById($oMenuNode->GetMenuId());
|
$index = self::GetMenuIndexById($oMenuNode->GetMenuId());
|
||||||
if ($index == -1)
|
if ($index == -1) {
|
||||||
{
|
|
||||||
// The menu does not already exist, insert it
|
// The menu does not already exist, insert it
|
||||||
$index = count(self::$aMenusIndex);
|
$index = count(self::$aMenusIndex);
|
||||||
|
|
||||||
if ($iParentIndex == -1)
|
if ($iParentIndex == -1) {
|
||||||
{
|
|
||||||
$sParentId = '';
|
$sParentId = '';
|
||||||
self::$aRootMenus[] = array ('rank' => $fRank, 'index' => $index);
|
self::$aRootMenus[] = ['rank' => $fRank, 'index' => $index];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/** @var \MenuNode $oNode */
|
/** @var \MenuNode $oNode */
|
||||||
$oNode = self::$aMenusIndex[$iParentIndex]['node'];
|
$oNode = self::$aMenusIndex[$iParentIndex]['node'];
|
||||||
$sParentId = $oNode->GetMenuId();
|
$sParentId = $oNode->GetMenuId();
|
||||||
self::$aMenusIndex[$iParentIndex]['children'][] = array ('rank' => $fRank, 'index' => $index);
|
self::$aMenusIndex[$iParentIndex]['children'][] = ['rank' => $fRank, 'index' => $index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: At the time when 'parent', 'rank' and 'source_file' have been added for the reflection API,
|
// Note: At the time when 'parent', 'rank' and 'source_file' have been added for the reflection API,
|
||||||
@@ -183,11 +175,9 @@ class ApplicationMenu
|
|||||||
//
|
//
|
||||||
$aBacktrace = debug_backtrace();
|
$aBacktrace = debug_backtrace();
|
||||||
$sFile = isset($aBacktrace[2]["file"]) ? $aBacktrace[2]["file"] : $aBacktrace[1]["file"];
|
$sFile = isset($aBacktrace[2]["file"]) ? $aBacktrace[2]["file"] : $aBacktrace[1]["file"];
|
||||||
self::$aMenusIndex[$index] = array('node' => $oMenuNode, 'children' => array(), 'parent' => $sParentId, 'rank' => $fRank, 'source_file' => $sFile);
|
self::$aMenusIndex[$index] = ['node' => $oMenuNode, 'children' => [], 'parent' => $sParentId, 'rank' => $fRank, 'source_file' => $sFile];
|
||||||
self::$aMenusById[$oMenuNode->GetMenuId()] = $index;
|
self::$aMenusById[$oMenuNode->GetMenuId()] = $index;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// the menu already exists, let's combine the conditions that make it visible
|
// the menu already exists, let's combine the conditions that make it visible
|
||||||
/** @var \MenuNode $oNode */
|
/** @var \MenuNode $oNode */
|
||||||
$oNode = self::$aMenusIndex[$index]['node'];
|
$oNode = self::$aMenusIndex[$index]['node'];
|
||||||
@@ -217,7 +207,7 @@ class ApplicationMenu
|
|||||||
* @throws \DictExceptionMissingString
|
* @throws \DictExceptionMissingString
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
public static function GetMenusCount($aExtraParams = array())
|
public static function GetMenusCount($aExtraParams = [])
|
||||||
{
|
{
|
||||||
$aMenuGroups = static::GetMenuGroups($aExtraParams);
|
$aMenuGroups = static::GetMenuGroups($aExtraParams);
|
||||||
|
|
||||||
@@ -260,18 +250,16 @@ class ApplicationMenu
|
|||||||
* @throws \DictExceptionMissingString
|
* @throws \DictExceptionMissingString
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
public static function GetMenuGroups($aExtraParams = array())
|
public static function GetMenuGroups($aExtraParams = [])
|
||||||
{
|
{
|
||||||
self::LoadAdditionalMenus();
|
self::LoadAdditionalMenus();
|
||||||
|
|
||||||
// Sort the root menu based on the rank
|
// Sort the root menu based on the rank
|
||||||
usort(self::$aRootMenus, array('ApplicationMenu', 'CompareOnRank'));
|
usort(self::$aRootMenus, ['ApplicationMenu', 'CompareOnRank']);
|
||||||
|
|
||||||
$aMenuGroups = [];
|
$aMenuGroups = [];
|
||||||
foreach(static::$aRootMenus as $aMenuGroup)
|
foreach (static::$aRootMenus as $aMenuGroup) {
|
||||||
{
|
if (!static::CanDisplayMenu($aMenuGroup)) {
|
||||||
if(!static::CanDisplayMenu($aMenuGroup))
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,26 +310,23 @@ class ApplicationMenu
|
|||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
public static function GetSubMenuNodes($sMenuGroupIdx, $aExtraParams = array())
|
public static function GetSubMenuNodes($sMenuGroupIdx, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
$aSubMenuItems = self::GetChildren($sMenuGroupIdx);
|
$aSubMenuItems = self::GetChildren($sMenuGroupIdx);
|
||||||
|
|
||||||
// Sort the children based on the rank
|
// Sort the children based on the rank
|
||||||
usort($aSubMenuItems, array('ApplicationMenu', 'CompareOnRank'));
|
usort($aSubMenuItems, ['ApplicationMenu', 'CompareOnRank']);
|
||||||
|
|
||||||
$aSubMenuNodes = [];
|
$aSubMenuNodes = [];
|
||||||
foreach($aSubMenuItems as $aSubMenuItem)
|
foreach ($aSubMenuItems as $aSubMenuItem) {
|
||||||
{
|
if (!static::CanDisplayMenu($aSubMenuItem)) {
|
||||||
if(!static::CanDisplayMenu($aSubMenuItem))
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sSubMenuItemIdx = $aSubMenuItem['index'];
|
$sSubMenuItemIdx = $aSubMenuItem['index'];
|
||||||
$oSubMenuNode = static::GetMenuNode($sSubMenuItemIdx);
|
$oSubMenuNode = static::GetMenuNode($sSubMenuItemIdx);
|
||||||
|
|
||||||
if(!$oSubMenuNode->IsEnabled())
|
if (!$oSubMenuNode->IsEnabled()) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,7 +357,7 @@ class ApplicationMenu
|
|||||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('use static::GetMenuGroups() instead');
|
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('use static::GetMenuGroups() instead');
|
||||||
self::LoadAdditionalMenus();
|
self::LoadAdditionalMenus();
|
||||||
// Sort the root menu based on the rank
|
// Sort the root menu based on the rank
|
||||||
usort(self::$aRootMenus, array('ApplicationMenu', 'CompareOnRank'));
|
usort(self::$aRootMenus, ['ApplicationMenu', 'CompareOnRank']);
|
||||||
$iAccordion = 0;
|
$iAccordion = 0;
|
||||||
$iActiveAccordion = $iAccordion;
|
$iActiveAccordion = $iAccordion;
|
||||||
$iActiveMenu = self::GetMenuIndexById(self::GetActiveNodeId());
|
$iActiveMenu = self::GetMenuIndexById(self::GetActiveNodeId());
|
||||||
@@ -387,8 +372,7 @@ class ApplicationMenu
|
|||||||
$aChildren = self::GetChildren($aMenu['index']);
|
$aChildren = self::GetChildren($aMenu['index']);
|
||||||
$bActive = self::DisplaySubMenu($oPage, $aChildren, $aExtraParams, $iActiveMenu);
|
$bActive = self::DisplaySubMenu($oPage, $aChildren, $aExtraParams, $iActiveMenu);
|
||||||
$oPage->AddToMenu('</ul>');
|
$oPage->AddToMenu('</ul>');
|
||||||
if ($bActive)
|
if ($bActive) {
|
||||||
{
|
|
||||||
$iActiveAccordion = $iAccordion;
|
$iActiveAccordion = $iAccordion;
|
||||||
}
|
}
|
||||||
$oPage->AddToMenu('</div>');
|
$oPage->AddToMenu('</div>');
|
||||||
@@ -396,7 +380,7 @@ class ApplicationMenu
|
|||||||
}
|
}
|
||||||
|
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
// Accordion Menu
|
// Accordion Menu
|
||||||
$("#accordion").css({display:'block'}).accordion({ header: "h3", heightStyle: "content", collapsible: true, active: $iActiveAccordion, icons: false, animate: true }); // collapsible will be enabled once the item will be selected
|
$("#accordion").css({display:'block'}).accordion({ header: "h3", heightStyle: "content", collapsible: true, active: $iActiveAccordion, icons: false, animate: true }); // collapsible will be enabled once the item will be selected
|
||||||
EOF
|
EOF
|
||||||
@@ -411,21 +395,15 @@ EOF
|
|||||||
private static function CanDisplayMenu($aMenu)
|
private static function CanDisplayMenu($aMenu)
|
||||||
{
|
{
|
||||||
$oMenuNode = self::GetMenuNode($aMenu['index']);
|
$oMenuNode = self::GetMenuNode($aMenu['index']);
|
||||||
if ($oMenuNode->IsEnabled())
|
if ($oMenuNode->IsEnabled()) {
|
||||||
{
|
|
||||||
$aChildren = self::GetChildren($aMenu['index']);
|
$aChildren = self::GetChildren($aMenu['index']);
|
||||||
if (count($aChildren) > 0)
|
if (count($aChildren) > 0) {
|
||||||
{
|
foreach ($aChildren as $aSubMenu) {
|
||||||
foreach($aChildren as $aSubMenu)
|
if (self::CanDisplayMenu($aSubMenu)) {
|
||||||
{
|
|
||||||
if (self::CanDisplayMenu($aSubMenu))
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -450,46 +428,38 @@ EOF
|
|||||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('use static::GetSubMenuNodes() instead');
|
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('use static::GetSubMenuNodes() instead');
|
||||||
// Sort the menu based on the rank
|
// Sort the menu based on the rank
|
||||||
$bActive = false;
|
$bActive = false;
|
||||||
usort($aMenus, array('ApplicationMenu', 'CompareOnRank'));
|
usort($aMenus, ['ApplicationMenu', 'CompareOnRank']);
|
||||||
foreach ($aMenus as $aMenu) {
|
foreach ($aMenus as $aMenu) {
|
||||||
if (!self::CanDisplayMenu($aMenu)) {
|
if (!self::CanDisplayMenu($aMenu)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$index = $aMenu['index'];
|
$index = $aMenu['index'];
|
||||||
$oMenu = self::GetMenuNode($index);
|
$oMenu = self::GetMenuNode($index);
|
||||||
if ($oMenu->IsEnabled())
|
if ($oMenu->IsEnabled()) {
|
||||||
{
|
|
||||||
$aChildren = self::GetChildren($index);
|
$aChildren = self::GetChildren($index);
|
||||||
$aCSSClasses = array('navigation-menu-item');
|
$aCSSClasses = ['navigation-menu-item'];
|
||||||
if (count($aChildren) > 0)
|
if (count($aChildren) > 0) {
|
||||||
{
|
|
||||||
$aCSSClasses[] = 'submenu';
|
$aCSSClasses[] = 'submenu';
|
||||||
}
|
}
|
||||||
$sHyperlink = $oMenu->GetHyperlink($aExtraParams);
|
$sHyperlink = $oMenu->GetHyperlink($aExtraParams);
|
||||||
$sItemHtml = '<li id="'.utils::GetSafeId('AccordionMenu_'.$oMenu->GetMenuID()).'" class="'.implode(' ', $aCSSClasses).'" data-menu-id="'.$oMenu->GetMenuID().'">';
|
$sItemHtml = '<li id="'.utils::GetSafeId('AccordionMenu_'.$oMenu->GetMenuID()).'" class="'.implode(' ', $aCSSClasses).'" data-menu-id="'.$oMenu->GetMenuID().'">';
|
||||||
if ($sHyperlink != '')
|
if ($sHyperlink != '') {
|
||||||
{
|
|
||||||
$sLinkTarget = '';
|
$sLinkTarget = '';
|
||||||
if ($oMenu->IsHyperLinkInNewWindow())
|
if ($oMenu->IsHyperLinkInNewWindow()) {
|
||||||
{
|
|
||||||
$sLinkTarget .= ' target="_blank"';
|
$sLinkTarget .= ' target="_blank"';
|
||||||
}
|
}
|
||||||
$sURL = '"'.$oMenu->GetHyperlink($aExtraParams).'"'.$sLinkTarget;
|
$sURL = '"'.$oMenu->GetHyperlink($aExtraParams).'"'.$sLinkTarget;
|
||||||
$sTitle = utils::HtmlEntities($oMenu->GetTitle());
|
$sTitle = utils::HtmlEntities($oMenu->GetTitle());
|
||||||
$sItemHtml .= "<a href={$sURL}>{$sTitle}</a>";
|
$sItemHtml .= "<a href={$sURL}>{$sTitle}</a>";
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sItemHtml .= $oMenu->GetTitle();
|
$sItemHtml .= $oMenu->GetTitle();
|
||||||
}
|
}
|
||||||
$sItemHtml .= '</li>';
|
$sItemHtml .= '</li>';
|
||||||
$oPage->AddToMenu($sItemHtml);
|
$oPage->AddToMenu($sItemHtml);
|
||||||
if ($iActiveMenu == $index)
|
if ($iActiveMenu == $index) {
|
||||||
{
|
|
||||||
$bActive = true;
|
$bActive = true;
|
||||||
}
|
}
|
||||||
if (count($aChildren) > 0)
|
if (count($aChildren) > 0) {
|
||||||
{
|
|
||||||
$oPage->AddToMenu('<ul>');
|
$oPage->AddToMenu('<ul>');
|
||||||
$bActive |= self::DisplaySubMenu($oPage, $aChildren, $aExtraParams, $iActiveMenu);
|
$bActive |= self::DisplaySubMenu($oPage, $aChildren, $aExtraParams, $iActiveMenu);
|
||||||
$oPage->AddToMenu('</ul>');
|
$oPage->AddToMenu('</ul>');
|
||||||
@@ -508,12 +478,10 @@ EOF
|
|||||||
public static function CompareOnRank($a, $b)
|
public static function CompareOnRank($a, $b)
|
||||||
{
|
{
|
||||||
$result = 1;
|
$result = 1;
|
||||||
if ($a['rank'] == $b['rank'])
|
if ($a['rank'] == $b['rank']) {
|
||||||
{
|
|
||||||
$result = 0;
|
$result = 0;
|
||||||
}
|
}
|
||||||
if ($a['rank'] < $b['rank'])
|
if ($a['rank'] < $b['rank']) {
|
||||||
{
|
|
||||||
$result = -1;
|
$result = -1;
|
||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
@@ -561,8 +529,7 @@ EOF
|
|||||||
{
|
{
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sMenuId = $oAppContext->GetCurrentValue('menu', null);
|
$sMenuId = $oAppContext->GetCurrentValue('menu', null);
|
||||||
if ($sMenuId === null)
|
if ($sMenuId === null) {
|
||||||
{
|
|
||||||
$sMenuId = self::GetDefaultMenuId();
|
$sMenuId = self::GetDefaultMenuId();
|
||||||
}
|
}
|
||||||
return $sMenuId;
|
return $sMenuId;
|
||||||
@@ -574,13 +541,12 @@ EOF
|
|||||||
public static function GetDefaultMenuId()
|
public static function GetDefaultMenuId()
|
||||||
{
|
{
|
||||||
static $sDefaultMenuId = null;
|
static $sDefaultMenuId = null;
|
||||||
if (is_null($sDefaultMenuId))
|
if (is_null($sDefaultMenuId)) {
|
||||||
{
|
|
||||||
// Make sure the root menu is sorted on 'rank'
|
// Make sure the root menu is sorted on 'rank'
|
||||||
usort(self::$aRootMenus, array('ApplicationMenu', 'CompareOnRank'));
|
usort(self::$aRootMenus, ['ApplicationMenu', 'CompareOnRank']);
|
||||||
$oFirstGroup = self::GetMenuNode(self::$aRootMenus[0]['index']);
|
$oFirstGroup = self::GetMenuNode(self::$aRootMenus[0]['index']);
|
||||||
$aChildren = self::$aMenusIndex[$oFirstGroup->GetIndex()]['children'];
|
$aChildren = self::$aMenusIndex[$oFirstGroup->GetIndex()]['children'];
|
||||||
usort($aChildren, array('ApplicationMenu', 'CompareOnRank'));
|
usort($aChildren, ['ApplicationMenu', 'CompareOnRank']);
|
||||||
$oMenuNode = self::GetMenuNode($aChildren[0]['index']);
|
$oMenuNode = self::GetMenuNode($aChildren[0]['index']);
|
||||||
$sDefaultMenuId = $oMenuNode->GetMenuId();
|
$sDefaultMenuId = $oMenuNode->GetMenuId();
|
||||||
}
|
}
|
||||||
@@ -594,13 +560,11 @@ EOF
|
|||||||
public static function GetRootMenuId($sMenuId)
|
public static function GetRootMenuId($sMenuId)
|
||||||
{
|
{
|
||||||
$iMenuIndex = self::GetMenuIndexById($sMenuId);
|
$iMenuIndex = self::GetMenuIndexById($sMenuId);
|
||||||
if ($iMenuIndex == -1)
|
if ($iMenuIndex == -1) {
|
||||||
{
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
$oMenu = ApplicationMenu::GetMenuNode($iMenuIndex);
|
$oMenu = ApplicationMenu::GetMenuNode($iMenuIndex);
|
||||||
while ($oMenu->GetParentIndex() != -1)
|
while ($oMenu->GetParentIndex() != -1) {
|
||||||
{
|
|
||||||
$oMenu = ApplicationMenu::GetMenuNode($oMenu->GetParentIndex());
|
$oMenu = ApplicationMenu::GetMenuNode($oMenu->GetParentIndex());
|
||||||
}
|
}
|
||||||
return $oMenu->GetMenuId();
|
return $oMenu->GetMenuId();
|
||||||
@@ -687,17 +651,17 @@ abstract class MenuNode
|
|||||||
{
|
{
|
||||||
$this->sMenuId = $sMenuId;
|
$this->sMenuId = $sMenuId;
|
||||||
$this->iParentIndex = $iParentIndex;
|
$this->iParentIndex = $iParentIndex;
|
||||||
$this->aReflectionProperties = array();
|
$this->aReflectionProperties = [];
|
||||||
if (utils::IsNotNullOrEmptyString($sEnableClass)) {
|
if (utils::IsNotNullOrEmptyString($sEnableClass)) {
|
||||||
$this->aReflectionProperties['enable_class'] = $sEnableClass;
|
$this->aReflectionProperties['enable_class'] = $sEnableClass;
|
||||||
$this->aReflectionProperties['enable_action'] = $iActionCode;
|
$this->aReflectionProperties['enable_action'] = $iActionCode;
|
||||||
$this->aReflectionProperties['enable_permission'] = $iAllowedResults;
|
$this->aReflectionProperties['enable_permission'] = $iAllowedResults;
|
||||||
$this->aReflectionProperties['enable_stimulus'] = $sEnableStimulus;
|
$this->aReflectionProperties['enable_stimulus'] = $sEnableStimulus;
|
||||||
}
|
}
|
||||||
$this->m_aEnableClasses = array($sEnableClass);
|
$this->m_aEnableClasses = [$sEnableClass];
|
||||||
$this->m_aEnableActions = array($iActionCode);
|
$this->m_aEnableActions = [$iActionCode];
|
||||||
$this->m_aEnableActionResults = array($iAllowedResults);
|
$this->m_aEnableActionResults = [$iAllowedResults];
|
||||||
$this->m_aEnableStimuli = array($sEnableStimulus);
|
$this->m_aEnableStimuli = [$sEnableStimulus];
|
||||||
$this->index = ApplicationMenu::InsertMenu($this, $iParentIndex, $fRank);
|
$this->index = ApplicationMenu::InsertMenu($this, $iParentIndex, $fRank);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -751,7 +715,6 @@ abstract class MenuNode
|
|||||||
$oSearch->SetShowObsoleteData(utils::ShowObsoleteData());
|
$oSearch->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||||
DBSearchHelper::AddContextFilter($oSearch);
|
DBSearchHelper::AddContextFilter($oSearch);
|
||||||
|
|
||||||
|
|
||||||
$oSet = new DBObjectSet($oSearch);
|
$oSet = new DBObjectSet($oSearch);
|
||||||
$iCount = $oSet->CountWithLimit(99);
|
$iCount = $oSet->CountWithLimit(99);
|
||||||
if ($iCount > 99) {
|
if ($iCount > 99) {
|
||||||
@@ -802,8 +765,7 @@ abstract class MenuNode
|
|||||||
*/
|
*/
|
||||||
public function PopulateChildMenus()
|
public function PopulateChildMenus()
|
||||||
{
|
{
|
||||||
foreach (ApplicationMenu::GetChildren($this->GetIndex()) as $aMenu)
|
foreach (ApplicationMenu::GetChildren($this->GetIndex()) as $aMenu) {
|
||||||
{
|
|
||||||
$index = $aMenu['index'];
|
$index = $aMenu['index'];
|
||||||
$oMenu = ApplicationMenu::GetMenuNode($index);
|
$oMenu = ApplicationMenu::GetMenuNode($index);
|
||||||
$oMenu->PopulateChildMenus();
|
$oMenu->PopulateChildMenus();
|
||||||
@@ -838,8 +800,7 @@ abstract class MenuNode
|
|||||||
*/
|
*/
|
||||||
public function AddCondition(MenuNode $oMenuNode)
|
public function AddCondition(MenuNode $oMenuNode)
|
||||||
{
|
{
|
||||||
foreach($oMenuNode->m_aEnableClasses as $index => $sClass )
|
foreach ($oMenuNode->m_aEnableClasses as $index => $sClass) {
|
||||||
{
|
|
||||||
$this->m_aEnableClasses[] = $sClass;
|
$this->m_aEnableClasses[] = $sClass;
|
||||||
$this->m_aEnableActions[] = $oMenuNode->m_aEnableActions[$index];
|
$this->m_aEnableActions[] = $oMenuNode->m_aEnableActions[$index];
|
||||||
$this->m_aEnableActionResults[] = $oMenuNode->m_aEnableActionResults[$index];
|
$this->m_aEnableActionResults[] = $oMenuNode->m_aEnableActionResults[$index];
|
||||||
@@ -852,33 +813,24 @@ abstract class MenuNode
|
|||||||
*/
|
*/
|
||||||
public function IsEnabled()
|
public function IsEnabled()
|
||||||
{
|
{
|
||||||
foreach($this->m_aEnableClasses as $index => $sClass)
|
foreach ($this->m_aEnableClasses as $index => $sClass) {
|
||||||
{
|
if ($sClass != null) {
|
||||||
if ($sClass != null)
|
if (MetaModel::IsValidClass($sClass)) {
|
||||||
{
|
if ($this->m_aEnableStimuli[$index] != null) {
|
||||||
if (MetaModel::IsValidClass($sClass))
|
if (!UserRights::IsStimulusAllowed($sClass, $this->m_aEnableStimuli[$index])) {
|
||||||
{
|
|
||||||
if ($this->m_aEnableStimuli[$index] != null)
|
|
||||||
{
|
|
||||||
if (!UserRights::IsStimulusAllowed($sClass, $this->m_aEnableStimuli[$index]))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->m_aEnableActions[$index] != null)
|
if ($this->m_aEnableActions[$index] != null) {
|
||||||
{
|
|
||||||
// Menus access rights ignore the archive mode
|
// Menus access rights ignore the archive mode
|
||||||
utils::PushArchiveMode(false);
|
utils::PushArchiveMode(false);
|
||||||
$iResult = UserRights::IsActionAllowed($sClass, $this->m_aEnableActions[$index]);
|
$iResult = UserRights::IsActionAllowed($sClass, $this->m_aEnableActions[$index]);
|
||||||
utils::PopArchiveMode();
|
utils::PopArchiveMode();
|
||||||
if (!($iResult & $this->m_aEnableActionResults[$index]))
|
if (!($iResult & $this->m_aEnableActionResults[$index])) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -891,7 +843,7 @@ abstract class MenuNode
|
|||||||
* @param array $aExtraParams
|
* @param array $aExtraParams
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public abstract function RenderContent(WebPage $oPage, $aExtraParams = array());
|
abstract public function RenderContent(WebPage $oPage, $aExtraParams = []);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $sHyperlink
|
* @param string $sHyperlink
|
||||||
@@ -900,16 +852,13 @@ abstract class MenuNode
|
|||||||
*/
|
*/
|
||||||
protected function AddParams($sHyperlink, $aExtraParams)
|
protected function AddParams($sHyperlink, $aExtraParams)
|
||||||
{
|
{
|
||||||
if (count($aExtraParams) > 0)
|
if (count($aExtraParams) > 0) {
|
||||||
{
|
$aQuery = [];
|
||||||
$aQuery = array();
|
|
||||||
$sSeparator = '?';
|
$sSeparator = '?';
|
||||||
if (strpos($sHyperlink, '?') !== false)
|
if (strpos($sHyperlink, '?') !== false) {
|
||||||
{
|
|
||||||
$sSeparator = '&';
|
$sSeparator = '&';
|
||||||
}
|
}
|
||||||
foreach($aExtraParams as $sName => $sValue)
|
foreach ($aExtraParams as $sName => $sValue) {
|
||||||
{
|
|
||||||
$aQuery[] = urlencode($sName).'='.urlencode($sValue);
|
$aQuery[] = urlencode($sName).'='.urlencode($sValue);
|
||||||
}
|
}
|
||||||
$sHyperlink .= $sSeparator.implode('&', $aQuery);
|
$sHyperlink .= $sSeparator.implode('&', $aQuery);
|
||||||
@@ -925,7 +874,7 @@ abstract class MenuNode
|
|||||||
class MenuGroup extends MenuNode
|
class MenuGroup extends MenuNode
|
||||||
{
|
{
|
||||||
/** @var string DEFAULT_DECORATION_CLASSES Set to null by default so it is replaced by initials when none is specified */
|
/** @var string DEFAULT_DECORATION_CLASSES Set to null by default so it is replaced by initials when none is specified */
|
||||||
const DEFAULT_DECORATION_CLASSES = null;
|
public const DEFAULT_DECORATION_CLASSES = null;
|
||||||
|
|
||||||
/** @var string The CSS classes used to display the menu group's icon */
|
/** @var string The CSS classes used to display the menu group's icon */
|
||||||
protected $sDecorationClasses = self::DEFAULT_DECORATION_CLASSES;
|
protected $sDecorationClasses = self::DEFAULT_DECORATION_CLASSES;
|
||||||
@@ -945,8 +894,7 @@ class MenuGroup extends MenuNode
|
|||||||
{
|
{
|
||||||
parent::__construct($sMenuId, -1 /* no parent, groups are at root level */, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
parent::__construct($sMenuId, -1 /* no parent, groups are at root level */, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
||||||
|
|
||||||
if(!empty($sDecorationClasses))
|
if (!empty($sDecorationClasses)) {
|
||||||
{
|
|
||||||
$this->sDecorationClasses = $sDecorationClasses;
|
$this->sDecorationClasses = $sDecorationClasses;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -987,7 +935,7 @@ class MenuGroup extends MenuNode
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
assert(false); // Shall never be called, groups do not display any content
|
assert(false); // Shall never be called, groups do not display any content
|
||||||
}
|
}
|
||||||
@@ -1027,7 +975,9 @@ class TemplateMenuNode extends MenuNode
|
|||||||
*/
|
*/
|
||||||
public function GetHyperlink($aExtraParams)
|
public function GetHyperlink($aExtraParams)
|
||||||
{
|
{
|
||||||
if ($this->sTemplateFile == '') return '';
|
if ($this->sTemplateFile == '') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
return parent::GetHyperlink($aExtraParams);
|
return parent::GetHyperlink($aExtraParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1035,18 +985,15 @@ class TemplateMenuNode extends MenuNode
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
||||||
$sTemplate = @file_get_contents($this->sTemplateFile);
|
$sTemplate = @file_get_contents($this->sTemplateFile);
|
||||||
if ($sTemplate !== false)
|
if ($sTemplate !== false) {
|
||||||
{
|
|
||||||
$aExtraParams['table_id'] = 'Menu_'.$this->GetMenuId();
|
$aExtraParams['table_id'] = 'Menu_'.$this->GetMenuId();
|
||||||
$oTemplate = new DisplayTemplate($sTemplate);
|
$oTemplate = new DisplayTemplate($sTemplate);
|
||||||
$oTemplate->Render($oPage, $aExtraParams);
|
$oTemplate->Render($oPage, $aExtraParams);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oPage->p("Error: failed to load template file: '{$this->sTemplateFile}'"); // No need to translate ?
|
$oPage->p("Error: failed to load template file: '{$this->sTemplateFile}'"); // No need to translate ?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1080,7 +1027,6 @@ class OQLMenuNode extends MenuNode
|
|||||||
*/
|
*/
|
||||||
protected $m_aParams;
|
protected $m_aParams;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a menu item based on an OQL query and inserts it into the application's main menu
|
* Create a menu item based on an OQL query and inserts it into the application's main menu
|
||||||
* @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary)
|
* @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary)
|
||||||
@@ -1101,7 +1047,7 @@ class OQLMenuNode extends MenuNode
|
|||||||
$this->sOQL = $sOQL;
|
$this->sOQL = $sOQL;
|
||||||
$this->bSearch = $bSearch;
|
$this->bSearch = $bSearch;
|
||||||
$this->bSearchFormOpen = $bSearchFormOpen;
|
$this->bSearchFormOpen = $bSearchFormOpen;
|
||||||
$this->m_aParams = array();
|
$this->m_aParams = [];
|
||||||
$this->aReflectionProperties['oql'] = $sOQL;
|
$this->aReflectionProperties['oql'] = $sOQL;
|
||||||
$this->aReflectionProperties['do_search'] = $bSearch;
|
$this->aReflectionProperties['do_search'] = $bSearch;
|
||||||
// Enhancement: we could set as the "enable" condition that the user has enough rights to "read" the objects
|
// Enhancement: we could set as the "enable" condition that the user has enough rights to "read" the objects
|
||||||
@@ -1115,8 +1061,7 @@ class OQLMenuNode extends MenuNode
|
|||||||
public function SetParameters($aParams)
|
public function SetParameters($aParams)
|
||||||
{
|
{
|
||||||
$this->m_aParams = $aParams;
|
$this->m_aParams = $aParams;
|
||||||
foreach($aParams as $sKey => $value)
|
foreach ($aParams as $sKey => $value) {
|
||||||
{
|
|
||||||
$this->aReflectionProperties[$sKey] = $value;
|
$this->aReflectionProperties[$sKey] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1125,12 +1070,11 @@ class OQLMenuNode extends MenuNode
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
$oTag = new ContextTag(ContextTag::TAG_OBJECT_SEARCH);
|
$oTag = new ContextTag(ContextTag::TAG_OBJECT_SEARCH);
|
||||||
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
||||||
OQLMenuNode::RenderOQLSearch
|
OQLMenuNode::RenderOQLSearch(
|
||||||
(
|
|
||||||
$this->sOQL,
|
$this->sOQL,
|
||||||
Dict::S($this->sPageTitle),
|
Dict::S($this->sPageTitle),
|
||||||
'Menu_'.$this->GetMenuId(),
|
'Menu_'.$this->GetMenuId(),
|
||||||
@@ -1155,26 +1099,25 @@ class OQLMenuNode extends MenuNode
|
|||||||
* @throws DictExceptionMissingString
|
* @throws DictExceptionMissingString
|
||||||
* @throws OQLException
|
* @throws OQLException
|
||||||
*/
|
*/
|
||||||
public static function RenderOQLSearch($sOql, $sTitle, $sUsageId, $bSearchPane, $bSearchOpen, WebPage $oPage, $aExtraParams = array(), $bEnableBreadcrumb = false)
|
public static function RenderOQLSearch($sOql, $sTitle, $sUsageId, $bSearchPane, $bSearchOpen, WebPage $oPage, $aExtraParams = [], $bEnableBreadcrumb = false)
|
||||||
{
|
{
|
||||||
$sUsageId = utils::GetSafeId($sUsageId);
|
$sUsageId = utils::GetSafeId($sUsageId);
|
||||||
$oSearch = DBObjectSearch::FromOQL($sOql);
|
$oSearch = DBObjectSearch::FromOQL($sOql);
|
||||||
$sClass= $oSearch->GetClass();
|
$sClass = $oSearch->GetClass();
|
||||||
$sIcon = MetaModel::GetClassIcon($sClass, false);
|
$sIcon = MetaModel::GetClassIcon($sClass, false);
|
||||||
if ($bSearchPane) {
|
if ($bSearchPane) {
|
||||||
$aParams = array_merge(['open' => $bSearchOpen, 'table_id' => $sUsageId, 'submit_on_load' => false], $aExtraParams);
|
$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, DisplayBlock::ENUM_STYLE_SEARCH, false /* Asynchronous */, $aParams);
|
||||||
$oBlock->Display($oPage, 0);
|
$oBlock->Display($oPage, 0);
|
||||||
$oPage->add("<div class='sf_results_area ibo-add-margin-top-250' data-target='search_results'>");
|
$oPage->add("<div class='sf_results_area ibo-add-margin-top-250' data-target='search_results'>");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
$oPage->add("<div class='sf_results_area' data-target='search_results'>");
|
$oPage->add("<div class='sf_results_area' data-target='search_results'>");
|
||||||
}
|
}
|
||||||
$aExtraParams['panel_class'] =$sClass;
|
$aExtraParams['panel_class'] = $sClass;
|
||||||
$aExtraParams['panel_title'] = $sTitle;
|
$aExtraParams['panel_title'] = $sTitle;
|
||||||
$aExtraParams['panel_icon'] = $sIcon;
|
$aExtraParams['panel_icon'] = $sIcon;
|
||||||
|
|
||||||
$aParams = array_merge(array('table_id' => $sUsageId), $aExtraParams);
|
$aParams = array_merge(['table_id' => $sUsageId], $aExtraParams);
|
||||||
$oBlock = new DisplayBlock($oSearch, 'list', false /* Asynchronous */, $aParams);
|
$oBlock = new DisplayBlock($oSearch, 'list', false /* Asynchronous */, $aParams);
|
||||||
$oBlock->Display($oPage, $sUsageId);
|
$oBlock->Display($oPage, $sUsageId);
|
||||||
|
|
||||||
@@ -1239,14 +1182,14 @@ class SearchMenuNode extends MenuNode
|
|||||||
* @throws \DictExceptionMissingString
|
* @throws \DictExceptionMissingString
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
||||||
$oPage->SetBreadCrumbEntry("menu-".$this->sMenuId, $this->GetTitle(), '', '', 'fas fa-search', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
$oPage->SetBreadCrumbEntry("menu-".$this->sMenuId, $this->GetTitle(), '', '', 'fas fa-search', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||||
|
|
||||||
$oSearch = new DBObjectSearch($this->sClass);
|
$oSearch = new DBObjectSearch($this->sClass);
|
||||||
$sUsageId = 'Menu_'.utils::GetSafeId($this->GetMenuId());
|
$sUsageId = 'Menu_'.utils::GetSafeId($this->GetMenuId());
|
||||||
$aParams = array_merge(array('table_id' =>$sUsageId), $aExtraParams);
|
$aParams = array_merge(['table_id' => $sUsageId], $aExtraParams);
|
||||||
$oBlock = new DisplayBlock($oSearch, 'search', false /* Asynchronous */, $aParams);
|
$oBlock = new DisplayBlock($oSearch, 'search', false /* Asynchronous */, $aParams);
|
||||||
$oBlock->Display($oPage, 0);
|
$oBlock->Display($oPage, 0);
|
||||||
}
|
}
|
||||||
@@ -1283,10 +1226,16 @@ class WebPageMenuNode extends MenuNode
|
|||||||
* @param bool $bIsLinkInNewWindow for the {@link WebPageMenuNode::IsHyperLinkInNewWindow} method
|
* @param bool $bIsLinkInNewWindow for the {@link WebPageMenuNode::IsHyperLinkInNewWindow} method
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
$sMenuId, $sHyperlink, $iParentIndex, $fRank = 0.0, $sEnableClass = null, $iActionCode = null,
|
$sMenuId,
|
||||||
$iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null, $bIsLinkInNewWindow = false
|
$sHyperlink,
|
||||||
)
|
$iParentIndex,
|
||||||
{
|
$fRank = 0.0,
|
||||||
|
$sEnableClass = null,
|
||||||
|
$iActionCode = null,
|
||||||
|
$iAllowedResults = UR_ALLOWED_YES,
|
||||||
|
$sEnableStimulus = null,
|
||||||
|
$bIsLinkInNewWindow = false
|
||||||
|
) {
|
||||||
parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
|
||||||
$this->sHyperlink = $sHyperlink;
|
$this->sHyperlink = $sHyperlink;
|
||||||
$this->aReflectionProperties['url'] = $sHyperlink;
|
$this->aReflectionProperties['url'] = $sHyperlink;
|
||||||
@@ -1299,7 +1248,7 @@ class WebPageMenuNode extends MenuNode
|
|||||||
public function GetHyperlink($aExtraParams)
|
public function GetHyperlink($aExtraParams)
|
||||||
{
|
{
|
||||||
$aExtraParams['c[menu]'] = $this->GetMenuId();
|
$aExtraParams['c[menu]'] = $this->GetMenuId();
|
||||||
return $this->AddParams( $this->sHyperlink, $aExtraParams);
|
return $this->AddParams($this->sHyperlink, $aExtraParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1313,7 +1262,7 @@ class WebPageMenuNode extends MenuNode
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
assert(false); // Shall never be called, the external web page will handle the display by itself
|
assert(false); // Shall never be called, the external web page will handle the display by itself
|
||||||
}
|
}
|
||||||
@@ -1374,10 +1323,8 @@ class NewObjectMenuNode extends MenuNode
|
|||||||
$aSubClasses = MetaModel::EnumChildClasses($this->sClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
|
$aSubClasses = MetaModel::EnumChildClasses($this->sClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
|
||||||
$bActionIsAllowed = false;
|
$bActionIsAllowed = false;
|
||||||
|
|
||||||
foreach($aSubClasses as $sCandidateClass)
|
foreach ($aSubClasses as $sCandidateClass) {
|
||||||
{
|
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES)) {
|
||||||
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES))
|
|
||||||
{
|
|
||||||
$bActionIsAllowed = true;
|
$bActionIsAllowed = true;
|
||||||
break; // Enough for now
|
break; // Enough for now
|
||||||
}
|
}
|
||||||
@@ -1388,7 +1335,7 @@ class NewObjectMenuNode extends MenuNode
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
assert(false); // Shall never be called, the external web page will handle the display by itself
|
assert(false); // Shall never be called, the external web page will handle the display by itself
|
||||||
}
|
}
|
||||||
@@ -1428,7 +1375,9 @@ class DashboardMenuNode extends MenuNode
|
|||||||
*/
|
*/
|
||||||
public function GetHyperlink($aExtraParams)
|
public function GetHyperlink($aExtraParams)
|
||||||
{
|
{
|
||||||
if ($this->sDashboardFile == '') return '';
|
if ($this->sDashboardFile == '') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
return parent::GetHyperlink($aExtraParams);
|
return parent::GetHyperlink($aExtraParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1446,12 +1395,11 @@ class DashboardMenuNode extends MenuNode
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
||||||
$oDashboard = $this->GetDashboard();
|
$oDashboard = $this->GetDashboard();
|
||||||
if ($oDashboard != null)
|
if ($oDashboard != null) {
|
||||||
{
|
|
||||||
WebResourcesHelper::EnableC3JSToWebPage($oPage);
|
WebResourcesHelper::EnableC3JSToWebPage($oPage);
|
||||||
|
|
||||||
$sDivId = utils::Sanitize($this->sMenuId, '', 'element_identifier');
|
$sDivId = utils::Sanitize($this->sMenuId, '', 'element_identifier');
|
||||||
@@ -1482,9 +1430,7 @@ class DashboardMenuNode extends MenuNode
|
|||||||
}
|
}
|
||||||
$oPage->SetBreadCrumbEntry("ui-dashboard-".$this->sMenuId, $this->GetTitle(), $sDescription, '', $sIcon, iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
$oPage->SetBreadCrumbEntry("ui-dashboard-".$this->sMenuId, $this->GetTitle(), $sDescription, '', $sIcon, iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oPage->p("Error: failed to load dashboard file: '{$this->sDashboardFile}'");
|
$oPage->p("Error: failed to load dashboard file: '{$this->sDashboardFile}'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1497,12 +1443,9 @@ class DashboardMenuNode extends MenuNode
|
|||||||
public function RenderEditor(WebPage $oPage)
|
public function RenderEditor(WebPage $oPage)
|
||||||
{
|
{
|
||||||
$oDashboard = $this->GetDashboard();
|
$oDashboard = $this->GetDashboard();
|
||||||
if ($oDashboard != null)
|
if ($oDashboard != null) {
|
||||||
{
|
|
||||||
$oDashboard->RenderEditor($oPage);
|
$oDashboard->RenderEditor($oPage);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oPage->p("Error: failed to load dashboard file: '{$this->sDashboardFile}'");
|
$oPage->p("Error: failed to load dashboard file: '{$this->sDashboardFile}'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1514,13 +1457,10 @@ class DashboardMenuNode extends MenuNode
|
|||||||
public function AddDashlet($oDashlet)
|
public function AddDashlet($oDashlet)
|
||||||
{
|
{
|
||||||
$oDashboard = $this->GetDashboard();
|
$oDashboard = $this->GetDashboard();
|
||||||
if ($oDashboard != null)
|
if ($oDashboard != null) {
|
||||||
{
|
|
||||||
$oDashboard->AddDashlet($oDashlet);
|
$oDashboard->AddDashlet($oDashlet);
|
||||||
$oDashboard->Save();
|
$oDashboard->Save();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new Exception("Error: failed to load dashboard file: '{$this->sDashboardFile}'");
|
throw new Exception("Error: failed to load dashboard file: '{$this->sDashboardFile}'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1543,7 +1483,7 @@ class ShortcutContainerMenuNode extends MenuNode
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1558,10 +1498,9 @@ class ShortcutContainerMenuNode extends MenuNode
|
|||||||
//
|
//
|
||||||
$oBMSearch = new DBObjectSearch('Shortcut');
|
$oBMSearch = new DBObjectSearch('Shortcut');
|
||||||
$oBMSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
$oBMSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||||
$oBMSet = new DBObjectSet($oBMSearch, array('friendlyname' => true)); // ascending on friendlyname
|
$oBMSet = new DBObjectSet($oBMSearch, ['friendlyname' => true]); // ascending on friendlyname
|
||||||
$fRank = 1;
|
$fRank = 1;
|
||||||
while ($oShortcut = $oBMSet->Fetch())
|
while ($oShortcut = $oBMSet->Fetch()) {
|
||||||
{
|
|
||||||
$sName = $this->GetMenuId().'_'.$oShortcut->GetKey();
|
$sName = $this->GetMenuId().'_'.$oShortcut->GetKey();
|
||||||
new ShortcutMenuNode($sName, $oShortcut, $this->GetIndex(), $fRank++);
|
new ShortcutMenuNode($sName, $oShortcut, $this->GetIndex(), $fRank++);
|
||||||
}
|
}
|
||||||
@@ -1572,7 +1511,6 @@ class ShortcutContainerMenuNode extends MenuNode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
require_once(APPROOT.'application/shortcut.class.inc.php');
|
require_once(APPROOT.'application/shortcut.class.inc.php');
|
||||||
/**
|
/**
|
||||||
* This class defines a menu item which content is a shortcut.
|
* This class defines a menu item which content is a shortcut.
|
||||||
@@ -1609,12 +1547,10 @@ class ShortcutMenuNode extends MenuNode
|
|||||||
{
|
{
|
||||||
$sContext = $this->oShortcut->Get('context');
|
$sContext = $this->oShortcut->Get('context');
|
||||||
$aContext = unserialize($sContext);
|
$aContext = unserialize($sContext);
|
||||||
if (isset($aContext['menu']))
|
if (isset($aContext['menu'])) {
|
||||||
{
|
|
||||||
unset($aContext['menu']);
|
unset($aContext['menu']);
|
||||||
}
|
}
|
||||||
foreach ($aContext as $sArgName => $sArgValue)
|
foreach ($aContext as $sArgName => $sArgValue) {
|
||||||
{
|
|
||||||
$aExtraParams[$sArgName] = $sArgValue;
|
$aExtraParams[$sArgName] = $sArgValue;
|
||||||
}
|
}
|
||||||
return parent::GetHyperlink($aExtraParams);
|
return parent::GetHyperlink($aExtraParams);
|
||||||
@@ -1624,7 +1560,7 @@ class ShortcutMenuNode extends MenuNode
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
|
||||||
$this->oShortcut->RenderContent($oPage, $aExtraParams);
|
$this->oShortcut->RenderContent($oPage, $aExtraParams);
|
||||||
@@ -1661,11 +1597,9 @@ class ShortcutMenuNode extends MenuNode
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function GetEntriesCount()
|
public function GetEntriesCount()
|
||||||
{
|
{
|
||||||
return $this->GetEntriesCountFromOQL($this->oShortcut->Get('oql'));
|
return $this->GetEntriesCountFromOQL($this->oShortcut->Get('oql'));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -34,44 +35,44 @@ interface iNewsroomProvider
|
|||||||
* return bool
|
* return bool
|
||||||
*/
|
*/
|
||||||
public function IsApplicable(User $oUser = null);
|
public function IsApplicable(User $oUser = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The human readable (localized) label for this provider
|
* The human readable (localized) label for this provider
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function GetLabel();
|
public function GetLabel();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The URL to query (from the browser, using jsonp) to fetch all unread messages
|
* The URL to query (from the browser, using jsonp) to fetch all unread messages
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function GetFetchURL();
|
public function GetFetchURL();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The URL to navigate to in order to display all messages
|
* The URL to navigate to in order to display all messages
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function GetViewAllURL();
|
public function GetViewAllURL();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The URL to query(from the browser, using jsonp) to mark all unread messages as read
|
* The URL to query(from the browser, using jsonp) to mark all unread messages as read
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function GetMarkAllAsReadURL();
|
public function GetMarkAllAsReadURL();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the URL to configure the preferences for this provider or null is there is nothing to configure
|
* Return the URL to configure the preferences for this provider or null is there is nothing to configure
|
||||||
* @return string|null
|
* @return string|null
|
||||||
*/
|
*/
|
||||||
public function GetPreferencesUrl();
|
public function GetPreferencesUrl();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an array key => value to be replaced in URL of the messages
|
* Return an array key => value to be replaced in URL of the messages
|
||||||
* Example: '%itop_root%' => utils::GetAbsoluteUrlAppRoot();
|
* Example: '%itop_root%' => utils::GetAbsoluteUrlAppRoot();
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
public function GetPlaceholders();
|
public function GetPlaceholders();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The duration between to refreshes of the cache (in seconds)
|
* The duration between to refreshes of the cache (in seconds)
|
||||||
* @return int
|
* @return int
|
||||||
@@ -90,19 +91,19 @@ abstract class NewsroomProviderBase implements iNewsroomProvider
|
|||||||
* @var Config
|
* @var Config
|
||||||
*/
|
*/
|
||||||
protected $oConfig;
|
protected $oConfig;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->oConfig = null;
|
$this->oConfig = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* @see iNewsroomProvider::SetConfig()
|
* @see iNewsroomProvider::SetConfig()
|
||||||
*/
|
*/
|
||||||
public function SetConfig(Config $oConfig)
|
public function SetConfig(Config $oConfig)
|
||||||
{
|
{
|
||||||
$this->oConfig = $oConfig;
|
$this->oConfig = $oConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,42 +119,42 @@ abstract class NewsroomProviderBase implements iNewsroomProvider
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* @see iNewsroomProvider::GetLabel()
|
* @see iNewsroomProvider::GetLabel()
|
||||||
*/
|
*/
|
||||||
public abstract function GetLabel();
|
abstract public function GetLabel();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* @see iNewsroomProvider::GetFetchURL()
|
* @see iNewsroomProvider::GetFetchURL()
|
||||||
*/
|
*/
|
||||||
public abstract function GetFetchURL();
|
abstract public function GetFetchURL();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* @see iNewsroomProvider::GetMarkAllURL()
|
* @see iNewsroomProvider::GetMarkAllURL()
|
||||||
*/
|
*/
|
||||||
public abstract function GetMarkAllAsReadURL();
|
abstract public function GetMarkAllAsReadURL();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* @see iNewsroomProvider::GetViewAllURL()
|
* @see iNewsroomProvider::GetViewAllURL()
|
||||||
*/
|
*/
|
||||||
public abstract function GetViewAllURL();
|
abstract public function GetViewAllURL();
|
||||||
|
|
||||||
public function IsApplicable(User $oUser = null)
|
public function IsApplicable(User $oUser = null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* @see iNewsroomProvider::GetPlaceholders()
|
* @see iNewsroomProvider::GetPlaceholders()
|
||||||
*/
|
*/
|
||||||
public function GetPlaceholders()
|
public function GetPlaceholders()
|
||||||
{
|
{
|
||||||
return array(); // By default, empty set of placeholders
|
return []; // By default, empty set of placeholders
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetTTL()
|
public function GetTTL()
|
||||||
{
|
{
|
||||||
return 10*60; // Refresh every 10 minutes
|
return 10 * 60; // Refresh every 10 minutes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/NiceWebPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/NiceWebPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/NiceWebPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/NiceWebPage.php, now loadable using autoloader');
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/PDFPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/PDFPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/PDFPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/PDFPage.php, now loadable using autoloader');
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class PortalDispatcher
|
class PortalDispatcher
|
||||||
{
|
{
|
||||||
protected $sPortalid;
|
protected $sPortalid;
|
||||||
protected $aData;
|
protected $aData;
|
||||||
|
|
||||||
public function __construct($sPortalId)
|
public function __construct($sPortalId)
|
||||||
{
|
{
|
||||||
$this->sPortalid = $sPortalId;
|
$this->sPortalid = $sPortalId;
|
||||||
@@ -20,53 +21,45 @@ class PortalDispatcher
|
|||||||
{
|
{
|
||||||
$bRet = true;
|
$bRet = true;
|
||||||
$aProfiles = UserRights::ListProfiles($oUser);
|
$aProfiles = UserRights::ListProfiles($oUser);
|
||||||
|
|
||||||
foreach($this->aData['deny'] as $sDeniedProfile)
|
foreach ($this->aData['deny'] as $sDeniedProfile) {
|
||||||
{
|
|
||||||
// If one denied profile is present, it's enough => return false
|
// If one denied profile is present, it's enough => return false
|
||||||
if (in_array($sDeniedProfile, $aProfiles))
|
if (in_array($sDeniedProfile, $aProfiles)) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If there are some "allow" profiles, then by default the result is false
|
// If there are some "allow" profiles, then by default the result is false
|
||||||
// since the user must have at least one of the profiles to be allowed
|
// since the user must have at least one of the profiles to be allowed
|
||||||
if (count($this->aData['allow']) > 0)
|
if (count($this->aData['allow']) > 0) {
|
||||||
{
|
|
||||||
$bRet = false;
|
$bRet = false;
|
||||||
}
|
}
|
||||||
foreach($this->aData['allow'] as $sAllowProfile)
|
foreach ($this->aData['allow'] as $sAllowProfile) {
|
||||||
{
|
|
||||||
// If one "allow" profile is present, it's enough => return true
|
// If one "allow" profile is present, it's enough => return true
|
||||||
if (in_array($sAllowProfile, $aProfiles))
|
if (in_array($sAllowProfile, $aProfiles)) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $bRet;
|
return $bRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetURL()
|
public function GetURL()
|
||||||
{
|
{
|
||||||
$aOverloads = MetaModel::GetConfig()->Get('portal_dispatch_urls');
|
$aOverloads = MetaModel::GetConfig()->Get('portal_dispatch_urls');
|
||||||
if (array_key_exists($this->sPortalid, $aOverloads))
|
if (array_key_exists($this->sPortalid, $aOverloads)) {
|
||||||
{
|
|
||||||
$sRet = $aOverloads[$this->sPortalid];
|
$sRet = $aOverloads[$this->sPortalid];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sRet = utils::GetAbsoluteUrlAppRoot().$this->aData['url'];
|
$sRet = utils::GetAbsoluteUrlAppRoot().$this->aData['url'];
|
||||||
}
|
}
|
||||||
return $sRet;
|
return $sRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetLabel()
|
public function GetLabel()
|
||||||
{
|
{
|
||||||
return Dict::S('portal:'.$this->sPortalid);
|
return Dict::S('portal:'.$this->sPortalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetRank()
|
public function GetRank()
|
||||||
{
|
{
|
||||||
return $this->aData['rank'];
|
return $this->aData['rank'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2010-2024 Combodo SAS
|
* Copyright (C) 2010-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
@@ -31,111 +32,117 @@ abstract class Query extends cmdbAbstractObject
|
|||||||
*/
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "core/cmdb,view_in_gui,application,grant_by_profile",
|
"category" => "core/cmdb,view_in_gui,application,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_query",
|
"db_table" => "priv_query",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "realclass",
|
"db_finalclass_field" => "realclass",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", array(
|
MetaModel::Init_AddAttribute(new AttributeString("name", [
|
||||||
"allowed_values" => null,
|
"allowed_values" => null,
|
||||||
"sql" => "name",
|
"sql" => "name",
|
||||||
"default_value" => null,
|
"default_value" => null,
|
||||||
"is_null_allowed" => false,
|
"is_null_allowed" => false,
|
||||||
"depends_on" => array(),
|
"depends_on" => [],
|
||||||
)));
|
]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeText("description", array(
|
MetaModel::Init_AddAttribute(new AttributeText("description", [
|
||||||
"allowed_values" => null,
|
"allowed_values" => null,
|
||||||
"sql" => "description",
|
"sql" => "description",
|
||||||
"default_value" => null,
|
"default_value" => null,
|
||||||
"is_null_allowed" => false,
|
"is_null_allowed" => false,
|
||||||
"depends_on" => array(),
|
"depends_on" => [],
|
||||||
)));
|
]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("is_template", array(
|
MetaModel::Init_AddAttribute(new AttributeEnum("is_template", [
|
||||||
'allowed_values' => new ValueSetEnum('yes,no'),
|
'allowed_values' => new ValueSetEnum('yes,no'),
|
||||||
'sql' => 'is_template',
|
'sql' => 'is_template',
|
||||||
'default_value' => 'no',
|
'default_value' => 'no',
|
||||||
'is_null_allowed' => false,
|
'is_null_allowed' => false,
|
||||||
'depends_on' => [],
|
'depends_on' => [],
|
||||||
'display_style' => 'radio_horizontal',
|
'display_style' => 'radio_horizontal',
|
||||||
)));
|
]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeInteger("export_count", array(
|
MetaModel::Init_AddAttribute(new AttributeInteger("export_count", [
|
||||||
"allowed_values" => null,
|
"allowed_values" => null,
|
||||||
"sql" => "export_count",
|
"sql" => "export_count",
|
||||||
"default_value" => 0,
|
"default_value" => 0,
|
||||||
"is_null_allowed" => false,
|
"is_null_allowed" => false,
|
||||||
"depends_on" => array(),
|
"depends_on" => [],
|
||||||
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
||||||
)));
|
]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeDateTime("export_last_date", array(
|
MetaModel::Init_AddAttribute(new AttributeDateTime("export_last_date", [
|
||||||
"allowed_values" => null,
|
"allowed_values" => null,
|
||||||
"sql" => "export_last_date",
|
"sql" => "export_last_date",
|
||||||
"default_value" => null,
|
"default_value" => null,
|
||||||
"is_null_allowed" => true,
|
"is_null_allowed" => true,
|
||||||
"depends_on" => array(),
|
"depends_on" => [],
|
||||||
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
||||||
)));
|
]));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("export_last_user_id",
|
MetaModel::Init_AddAttribute(new AttributeExternalKey(
|
||||||
array(
|
"export_last_user_id",
|
||||||
"targetclass"=>'User',
|
[
|
||||||
"allowed_values"=>null,
|
"targetclass" => 'User',
|
||||||
"sql"=>'user_id',
|
"allowed_values" => null,
|
||||||
"is_null_allowed"=>true,
|
"sql" => 'user_id',
|
||||||
"depends_on"=>array(),
|
"is_null_allowed" => true,
|
||||||
"display_style"=>'select',
|
"depends_on" => [],
|
||||||
"always_load_in_tables"=>false,
|
"display_style" => 'select',
|
||||||
"on_target_delete"=>DEL_SILENT,
|
"always_load_in_tables" => false,
|
||||||
|
"on_target_delete" => DEL_SILENT,
|
||||||
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
||||||
)));
|
]
|
||||||
|
));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("export_last_user_contact",
|
MetaModel::Init_AddAttribute(new AttributeExternalField(
|
||||||
array(
|
"export_last_user_contact",
|
||||||
"allowed_values"=>null,
|
[
|
||||||
"extkey_attcode"=> "export_last_user_id",
|
"allowed_values" => null,
|
||||||
"target_attcode"=>"contactid",
|
"extkey_attcode" => "export_last_user_id",
|
||||||
|
"target_attcode" => "contactid",
|
||||||
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
|
||||||
)));
|
]
|
||||||
|
));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details',
|
MetaModel::Init_SetZListItems(
|
||||||
array('name', 'is_template', 'description')); // Attributes to be displayed for the complete details
|
'details',
|
||||||
MetaModel::Init_SetZListItems('list', array('description')); // Attributes to be displayed for a list
|
['name', 'is_template', 'description']
|
||||||
|
); // Attributes to be displayed for the complete details
|
||||||
|
MetaModel::Init_SetZListItems('list', ['description']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'description', 'is_template')); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', ['name', 'description', 'is_template']); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('default_search',
|
MetaModel::Init_SetZListItems(
|
||||||
array('name', 'description', 'is_template')); // Criteria of the default search form
|
'default_search',
|
||||||
|
['name', 'description', 'is_template']
|
||||||
|
); // Criteria of the default search form
|
||||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*
|
*
|
||||||
* @since 3.1.0
|
* @since 3.1.0
|
||||||
*/
|
*/
|
||||||
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
public function GetAttributeFlags($sAttCode, &$aReasons = [], $sTargetState = '')
|
||||||
{
|
{
|
||||||
// read only attribute
|
// read only attribute
|
||||||
if (in_array($sAttCode, ['export_count', 'export_last_date', 'export_last_user_id'])){
|
if (in_array($sAttCode, ['export_count', 'export_last_date', 'export_last_user_id'])) {
|
||||||
return OPT_ATT_READONLY;
|
return OPT_ATT_READONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return export url.
|
* Return export url.
|
||||||
*
|
*
|
||||||
@@ -144,7 +151,7 @@ abstract class Query extends cmdbAbstractObject
|
|||||||
* @return string|null
|
* @return string|null
|
||||||
* @since 3.1.0
|
* @since 3.1.0
|
||||||
*/
|
*/
|
||||||
abstract public function GetExportUrl(array $aValues = null) : ?string;
|
abstract public function GetExportUrl(array $aValues = null): ?string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update last export information.
|
* Update last export information.
|
||||||
@@ -156,7 +163,7 @@ abstract class Query extends cmdbAbstractObject
|
|||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
* @since 3.1.0
|
* @since 3.1.0
|
||||||
*/
|
*/
|
||||||
public function UpdateLastExportInformation() : void
|
public function UpdateLastExportInformation(): void
|
||||||
{
|
{
|
||||||
// last export information
|
// last export information
|
||||||
$this->Set('export_last_date', date(AttributeDateTime::GetSQLFormat()));
|
$this->Set('export_last_date', date(AttributeDateTime::GetSQLFormat()));
|
||||||
@@ -173,53 +180,56 @@ class QueryOQL extends Query
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "core/cmdb,view_in_gui,application,grant_by_profile",
|
"category" => "core/cmdb,view_in_gui,application,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array('oql', 'is_template'),
|
"reconc_keys" => ['oql', 'is_template'],
|
||||||
"db_table" => "priv_query_oql",
|
"db_table" => "priv_query_oql",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_InheritAttributes();
|
MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeOQL("oql", array(
|
MetaModel::Init_AddAttribute(new AttributeOQL("oql", [
|
||||||
"allowed_values" => null,
|
"allowed_values" => null,
|
||||||
"sql" => "oql",
|
"sql" => "oql",
|
||||||
"default_value" => null,
|
"default_value" => null,
|
||||||
"is_null_allowed" => false,
|
"is_null_allowed" => false,
|
||||||
"depends_on" => array(),
|
"depends_on" => [],
|
||||||
)));
|
]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeText("fields", array(
|
MetaModel::Init_AddAttribute(new AttributeText("fields", [
|
||||||
"allowed_values" => null,
|
"allowed_values" => null,
|
||||||
"sql" => "fields",
|
"sql" => "fields",
|
||||||
"default_value" => null,
|
"default_value" => null,
|
||||||
"is_null_allowed" => true,
|
"is_null_allowed" => true,
|
||||||
"depends_on" => array(),
|
"depends_on" => [],
|
||||||
)));
|
]));
|
||||||
// Rolled back to AttributeText until AttributeQueryAttCodeSet can manage fields order correctly
|
// Rolled back to AttributeText until AttributeQueryAttCodeSet can manage fields order correctly
|
||||||
//MetaModel::Init_AddAttribute(new AttributeQueryAttCodeSet("fields", array("allowed_values"=>null,"max_items" => 1000, "query_field" => "oql", "sql"=>"fields", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array('oql'))));
|
//MetaModel::Init_AddAttribute(new AttributeQueryAttCodeSet("fields", array("allowed_values"=>null,"max_items" => 1000, "query_field" => "oql", "sql"=>"fields", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array('oql'))));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details',
|
MetaModel::Init_SetZListItems(
|
||||||
array(
|
'details',
|
||||||
'col:col1' => array('fieldset:Query:baseinfo' => array('name', 'is_template', 'description', 'oql', 'fields')),
|
[
|
||||||
'col:col2' => array('fieldset:Query:exportInfo' => array('export_count', 'export_last_date', 'export_last_user_id', 'export_last_user_contact'))
|
'col:col1' => ['fieldset:Query:baseinfo' => ['name', 'is_template', 'description', 'oql', 'fields']],
|
||||||
)
|
'col:col2' => ['fieldset:Query:exportInfo' => ['export_count', 'export_last_date', 'export_last_user_id', 'export_last_user_contact']],
|
||||||
|
]
|
||||||
); // Attributes to be displayed for the complete details
|
); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('description')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', ['description']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search',
|
MetaModel::Init_SetZListItems(
|
||||||
array('name', 'description', 'is_template', 'fields', 'oql')); // Criteria of the std search form
|
'standard_search',
|
||||||
|
['name', 'description', 'is_template', 'fields', 'oql']
|
||||||
|
); // Criteria of the std search form
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @inheritdoc */
|
/** @inheritdoc */
|
||||||
public function GetExportUrl(array $aValues = null) : ?string
|
public function GetExportUrl(array $aValues = null): ?string
|
||||||
{
|
{
|
||||||
try{
|
try {
|
||||||
// retrieve attributes
|
// retrieve attributes
|
||||||
$sFields = trim($this->Get('fields'));
|
$sFields = trim($this->Get('fields'));
|
||||||
$sOql = $this->Get('oql');
|
$sOql = $this->Get('oql');
|
||||||
@@ -228,8 +238,7 @@ class QueryOQL extends Query
|
|||||||
$bExportV1Recommended = ($sFields == '');
|
$bExportV1Recommended = ($sFields == '');
|
||||||
if ($bExportV1Recommended) {
|
if ($bExportV1Recommended) {
|
||||||
$sUrl = utils::GetAbsoluteUrlAppRoot().'webservices/export.php?format=spreadsheet&login_mode=basic&query='.$this->GetKey();
|
$sUrl = utils::GetAbsoluteUrlAppRoot().'webservices/export.php?format=spreadsheet&login_mode=basic&query='.$this->GetKey();
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
$sUrl = utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php?format=spreadsheet&login_mode=basic&date_format='.urlencode((string)AttributeDateTime::GetFormat()).'&query='.$this->GetKey();
|
$sUrl = utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php?format=spreadsheet&login_mode=basic&date_format='.urlencode((string)AttributeDateTime::GetFormat()).'&query='.$this->GetKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,17 +249,16 @@ class QueryOQL extends Query
|
|||||||
$aParameters = $oSearch->GetQueryParams();
|
$aParameters = $oSearch->GetQueryParams();
|
||||||
foreach ($aParameters as $sParam => $val) {
|
foreach ($aParameters as $sParam => $val) {
|
||||||
$paramValue = ($aValues === null || $aValues[$sParam] === null) ? $sParam : $aValues[$sParam];
|
$paramValue = ($aValues === null || $aValues[$sParam] === null) ? $sParam : $aValues[$sParam];
|
||||||
$sUrl .= '&arg_' . $sParam . '=' . $paramValue;
|
$sUrl .= '&arg_'.$sParam.'='.$paramValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sUrl;
|
return $sUrl;
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch(Exception $e){
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
|
public function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = [])
|
||||||
{
|
{
|
||||||
$aFieldsMap = parent::DisplayBareProperties($oPage, $bEditMode, $sPrefix, $aExtraParams);
|
$aFieldsMap = parent::DisplayBareProperties($oPage, $bEditMode, $sPrefix, $aExtraParams);
|
||||||
$oPage->add_script("$('[name=\"attr_oql\"]').addClass('ibo-query-oql ibo-is-code'); $('[data-attribute-code=\"oql\"]').addClass('ibo-query-oql ibo-is-code');");
|
$oPage->add_script("$('[name=\"attr_oql\"]').addClass('ibo-query-oql ibo-is-code'); $('[data-attribute-code=\"oql\"]').addClass('ibo-query-oql ibo-is-code');");
|
||||||
@@ -287,16 +295,14 @@ class QueryOQL extends Query
|
|||||||
|
|
||||||
if (count($aParameters) == 0) {
|
if (count($aParameters) == 0) {
|
||||||
$oBlock = new DisplayBlock($oSearch, 'list');
|
$oBlock = new DisplayBlock($oSearch, 'list');
|
||||||
$aExtraParams = array(
|
$aExtraParams = [
|
||||||
//'menu' => $sShowMenu,
|
//'menu' => $sShowMenu,
|
||||||
'table_id' => 'query_preview_'.$this->getKey(),
|
'table_id' => 'query_preview_'.$this->getKey(),
|
||||||
);
|
];
|
||||||
$sBlockId = 'block_query_preview_'.$this->GetKey(); // make a unique id (edition occuring in the same DOM)
|
$sBlockId = 'block_query_preview_'.$this->GetKey(); // make a unique id (edition occuring in the same DOM)
|
||||||
$oBlock->Display($oPage, $sBlockId, $aExtraParams);
|
$oBlock->Display($oPage, $sBlockId, $aExtraParams);
|
||||||
}
|
}
|
||||||
}
|
} catch (OQLException $e) {
|
||||||
catch
|
|
||||||
(OQLException $e) {
|
|
||||||
$oAlert = AlertUIBlockFactory::MakeForFailure(Dict::S('UI:RunQuery:Error'), $e->getHtmlDesc())
|
$oAlert = AlertUIBlockFactory::MakeForFailure(Dict::S('UI:RunQuery:Error'), $e->getHtmlDesc())
|
||||||
->SetIsClosable(false)
|
->SetIsClosable(false)
|
||||||
->SetIsCollapsible(false);
|
->SetIsCollapsible(false);
|
||||||
@@ -307,41 +313,38 @@ class QueryOQL extends Query
|
|||||||
return $aFieldsMap;
|
return $aFieldsMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rolled back until 'fields' can be properly managed by AttributeQueryAttCodeSet
|
||||||
// Rolled back until 'fields' can be properly managed by AttributeQueryAttCodeSet
|
//
|
||||||
//
|
// public function ComputeValues()
|
||||||
// public function ComputeValues()
|
// {
|
||||||
// {
|
// parent::ComputeValues();
|
||||||
// parent::ComputeValues();
|
//
|
||||||
//
|
// // Remove unwanted attribute codes
|
||||||
// // Remove unwanted attribute codes
|
// $aChanges = $this->ListChanges();
|
||||||
// $aChanges = $this->ListChanges();
|
// if (isset($aChanges['fields']))
|
||||||
// if (isset($aChanges['fields']))
|
// {
|
||||||
// {
|
// $oAttDef = MetaModel::GetAttributeDef(get_class($this), 'fields');
|
||||||
// $oAttDef = MetaModel::GetAttributeDef(get_class($this), 'fields');
|
// $aArgs = array('this' => $this);
|
||||||
// $aArgs = array('this' => $this);
|
// $aAllowedValues = $oAttDef->GetAllowedValues($aArgs);
|
||||||
// $aAllowedValues = $oAttDef->GetAllowedValues($aArgs);
|
//
|
||||||
//
|
// /** @var \ormSet $oValue */
|
||||||
// /** @var \ormSet $oValue */
|
// $oValue = $this->Get('fields');
|
||||||
// $oValue = $this->Get('fields');
|
// $aValues = $oValue->GetValues();
|
||||||
// $aValues = $oValue->GetValues();
|
// $bChanged = false;
|
||||||
// $bChanged = false;
|
// foreach($aValues as $key => $sValue)
|
||||||
// foreach($aValues as $key => $sValue)
|
// {
|
||||||
// {
|
// if (!isset($aAllowedValues[$sValue]))
|
||||||
// if (!isset($aAllowedValues[$sValue]))
|
// {
|
||||||
// {
|
// unset($aValues[$key]);
|
||||||
// unset($aValues[$key]);
|
// $bChanged = true;
|
||||||
// $bChanged = true;
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// if ($bChanged)
|
||||||
// if ($bChanged)
|
// {
|
||||||
// {
|
// $oValue->SetValues($aValues);
|
||||||
// $oValue->SetValues($aValues);
|
// $this->Set('fields', $oValue);
|
||||||
// $this->Set('fields', $oValue);
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// 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
|
// 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
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -18,7 +19,6 @@
|
|||||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
|
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
|
||||||
use Combodo\iTop\Application\WebPage\WebPage;
|
use Combodo\iTop\Application\WebPage\WebPage;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persistent class Shortcut and derived
|
* Persistent class Shortcut and derived
|
||||||
* Shortcuts of any kind
|
* Shortcuts of any kind
|
||||||
@@ -31,32 +31,32 @@ abstract class Shortcut extends DBObject implements iDisplay
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "gui,view_in_gui",
|
"category" => "gui,view_in_gui",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_shortcut",
|
"db_table" => "priv_shortcut",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "realclass",
|
"db_finalclass_field" => "realclass",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("user_id", array("targetclass"=>"User", "allowed_values"=>null, "sql"=>"user_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("user_id", ["targetclass" => "User", "allowed_values" => null, "sql" => "user_id", "is_null_allowed" => true, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeString("name", ["allowed_values" => null, "sql" => "name", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeText("context", array("allowed_values"=>null, "sql"=>"context", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeText("context", ["allowed_values" => null, "sql" => "context", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('name', 'context')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['name', 'context']); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('name')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', ['name']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract public function RenderContent(WebPage $oPage, $aExtraParams = array());
|
abstract public function RenderContent(WebPage $oPage, $aExtraParams = []);
|
||||||
|
|
||||||
protected function OnInsert()
|
protected function OnInsert()
|
||||||
{
|
{
|
||||||
@@ -74,14 +74,14 @@ abstract class Shortcut extends DBObject implements iDisplay
|
|||||||
$oForm->AddField($oField);
|
$oForm->AddField($oField);
|
||||||
$oForm->Render($oPage);
|
$oForm->Render($oPage);
|
||||||
$oPage->add('</div>');
|
$oPage->add('</div>');
|
||||||
|
|
||||||
$sDialogTitle = Dict::S('UI:ShortcutRenameDlg:Title');
|
$sDialogTitle = Dict::S('UI:ShortcutRenameDlg:Title');
|
||||||
$sOkButtonLabel = Dict::S('UI:Button:Ok');
|
$sOkButtonLabel = Dict::S('UI:Button:Ok');
|
||||||
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
||||||
$iShortcut = $this->GetKey();
|
$iShortcut = $this->GetKey();
|
||||||
|
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
function ShortcutRenameOK()
|
function ShortcutRenameOK()
|
||||||
{
|
{
|
||||||
var oForm = $(this).find('form');
|
var oForm = $(this).find('form');
|
||||||
@@ -137,13 +137,13 @@ EOF
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function DisplayDetails(WebPage $oPage, $bEditMode = false)
|
public function DisplayDetails(WebPage $oPage, $bEditMode = false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
|
public function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = [])
|
||||||
{
|
{
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
// End of the minimal implementation of iDisplay
|
// End of the minimal implementation of iDisplay
|
||||||
}
|
}
|
||||||
@@ -152,61 +152,56 @@ class ShortcutOQL extends Shortcut
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "gui,view_in_gui",
|
"category" => "gui,view_in_gui",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_shortcut_oql",
|
"db_table" => "priv_shortcut_oql",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
);
|
];
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_InheritAttributes();
|
MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeOQL("oql", array("allowed_values"=>null, "sql"=>"oql", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeOQL("oql", ["allowed_values" => null, "sql" => "oql", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("auto_reload", array("allowed_values"=>new ValueSetEnum('none,custom'), "sql"=>"auto_reload", "default_value"=>"none", "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeEnum("auto_reload", ["allowed_values" => new ValueSetEnum('none,custom'), "sql" => "auto_reload", "default_value" => "none", "is_null_allowed" => false, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeInteger("auto_reload_sec", array("allowed_values"=>null, "sql"=>"auto_reload_sec", "default_value"=>60, "is_null_allowed"=>false, "depends_on"=>array())));
|
MetaModel::Init_AddAttribute(new AttributeInteger("auto_reload_sec", ["allowed_values" => null, "sql" => "auto_reload_sec", "default_value" => 60, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', array('name', 'context', 'oql')); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', ['name', 'context', 'oql']); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', array('name')); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', ['name']); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
|
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
||||||
{
|
{
|
||||||
$oPage->set_title($this->Get('name'));
|
$oPage->set_title($this->Get('name'));
|
||||||
|
|
||||||
switch($this->Get('auto_reload'))
|
switch ($this->Get('auto_reload')) {
|
||||||
{
|
case 'custom':
|
||||||
case 'custom':
|
$iRate = (int)$this->Get('auto_reload_sec');
|
||||||
$iRate = (int)$this->Get('auto_reload_sec');
|
if ($iRate > 0) {
|
||||||
if ($iRate > 0)
|
// Must a string otherwise it can be evaluated to 'true' and defaults to "standard" refresh rate!
|
||||||
{
|
$aExtraParams['auto_reload'] = (string)$iRate;
|
||||||
// Must a string otherwise it can be evaluated to 'true' and defaults to "standard" refresh rate!
|
}
|
||||||
$aExtraParams['auto_reload'] = (string)$iRate;
|
break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
case 'none':
|
case 'none':
|
||||||
}
|
}
|
||||||
|
|
||||||
$bSearchPane = true;
|
$bSearchPane = true;
|
||||||
$bSearchOpen = true;
|
$bSearchOpen = true;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
OQLMenuNode::RenderOQLSearch($this->Get('oql'), $this->Get('name'), 'shortcut_'.$this->GetKey(), $bSearchPane, $bSearchOpen, $oPage, $aExtraParams, true);
|
OQLMenuNode::RenderOQLSearch($this->Get('oql'), $this->Get('name'), 'shortcut_'.$this->GetKey(), $bSearchPane, $bSearchOpen, $oPage, $aExtraParams, true);
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
throw new Exception("The OQL shortcut '".$this->Get('name')."' (id: ".$this->GetKey().") could not be displayed: ".$e->getMessage());
|
throw new Exception("The OQL shortcut '".$this->Get('name')."' (id: ".$this->GetKey().") could not be displayed: ".$e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function CloneTableSettings($sTableSettings)
|
public function CloneTableSettings($sTableSettings)
|
||||||
@@ -226,17 +221,14 @@ class ShortcutOQL extends Shortcut
|
|||||||
|
|
||||||
// Find a unique default name
|
// Find a unique default name
|
||||||
// -> The class of the query + an index if necessary
|
// -> The class of the query + an index if necessary
|
||||||
if ($sOQL == null)
|
if ($sOQL == null) {
|
||||||
{
|
|
||||||
$sDefault = '';
|
$sDefault = '';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oBMSearch = new DBObjectSearch('Shortcut');
|
$oBMSearch = new DBObjectSearch('Shortcut');
|
||||||
$oBMSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
$oBMSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||||
$oBMSet = new DBObjectSet($oBMSearch);
|
$oBMSet = new DBObjectSet($oBMSearch);
|
||||||
$aNames = $oBMSet->GetColumnAsArray('name');
|
$aNames = $oBMSet->GetColumnAsArray('name');
|
||||||
$oSearch = DBObjectSearch::FromOQL($sOQL);
|
$oSearch = DBObjectSearch::FromOQL($sOQL);
|
||||||
$sDefault = utils::MakeUniqueName($oSearch->GetClass(), $aNames);
|
$sDefault = utils::MakeUniqueName($oSearch->GetClass(), $aNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,18 +268,18 @@ class ShortcutOQL extends Shortcut
|
|||||||
|
|
||||||
$oForm->Render($oPage);
|
$oForm->Render($oPage);
|
||||||
$oPage->add('</div>');
|
$oPage->add('</div>');
|
||||||
|
|
||||||
$sDialogTitle = Dict::S('UI:ShortcutListDlg:Title');
|
$sDialogTitle = Dict::S('UI:ShortcutListDlg:Title');
|
||||||
$sOkButtonLabel = Dict::S('UI:Button:Ok');
|
$sOkButtonLabel = Dict::S('UI:Button:Ok');
|
||||||
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
||||||
|
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sContext = $oAppContext->GetForLink();
|
$sContext = $oAppContext->GetForLink();
|
||||||
|
|
||||||
$sRateTitle = addslashes(Dict::Format('Class:ShortcutOQL/Attribute:auto_reload_sec/tip', MetaModel::GetConfig()->Get('min_reload_interval')));
|
$sRateTitle = addslashes(Dict::Format('Class:ShortcutOQL/Attribute:auto_reload_sec/tip', MetaModel::GetConfig()->Get('min_reload_interval')));
|
||||||
|
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<JS
|
<<<JS
|
||||||
// Note: the title gets deleted by the validation mechanism
|
// Note: the title gets deleted by the validation mechanism
|
||||||
$("#attr_auto_reload_sec").attr('data-tooltip-content', '$sRateTitle');
|
$("#attr_auto_reload_sec").attr('data-tooltip-content', '$sRateTitle');
|
||||||
CombodoTooltip.InitTooltipFromMarkup($("#attr_auto_reload_sec"));
|
CombodoTooltip.InitTooltipFromMarkup($("#attr_auto_reload_sec"));
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -23,7 +24,6 @@ require_once(APPROOT.'core/contexttag.class.inc.php');
|
|||||||
require_once(APPROOT.'core/kpi.class.inc.php');
|
require_once(APPROOT.'core/kpi.class.inc.php');
|
||||||
require_once(APPROOT.'setup/setuputils.class.inc.php');
|
require_once(APPROOT.'setup/setuputils.class.inc.php');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File to include to initialize the datamodel in memory
|
* File to include to initialize the datamodel in memory
|
||||||
*
|
*
|
||||||
@@ -36,12 +36,10 @@ ExecutionKPI::EnableMemory(1);
|
|||||||
|
|
||||||
// This storage is freed on error (case of allowed memory exhausted)
|
// This storage is freed on error (case of allowed memory exhausted)
|
||||||
$sReservedMemory = str_repeat('*', 1024 * 1024);
|
$sReservedMemory = str_repeat('*', 1024 * 1024);
|
||||||
register_shutdown_function(function()
|
register_shutdown_function(function () {
|
||||||
{
|
|
||||||
global $sReservedMemory;
|
global $sReservedMemory;
|
||||||
$sReservedMemory = null;
|
$sReservedMemory = null;
|
||||||
if (!is_null($err = error_get_last()) && ($err['type'] == E_ERROR))
|
if (!is_null($err = error_get_last()) && ($err['type'] == E_ERROR)) {
|
||||||
{
|
|
||||||
// Remove stack trace from MySQLException (since 2.7.2 see N°3174)
|
// Remove stack trace from MySQLException (since 2.7.2 see N°3174)
|
||||||
$sMessage = $err['message'];
|
$sMessage = $err['message'];
|
||||||
if (strpos($sMessage, 'MySQLException') !== false) {
|
if (strpos($sMessage, 'MySQLException') !== false) {
|
||||||
@@ -71,38 +69,30 @@ $oKPI->ComputeAndReport("Session Start");
|
|||||||
|
|
||||||
$sSwitchEnv = utils::ReadParam('switch_env', null);
|
$sSwitchEnv = utils::ReadParam('switch_env', null);
|
||||||
$bAllowCache = true;
|
$bAllowCache = true;
|
||||||
if (($sSwitchEnv != null) && file_exists(APPCONF.$sSwitchEnv.'/'.ITOP_CONFIG_FILE) &&( Session::Get('itop_env') !== $sSwitchEnv))
|
if (($sSwitchEnv != null) && file_exists(APPCONF.$sSwitchEnv.'/'.ITOP_CONFIG_FILE) && (Session::Get('itop_env') !== $sSwitchEnv)) {
|
||||||
{
|
|
||||||
Session::Set('itop_env', $sSwitchEnv);
|
Session::Set('itop_env', $sSwitchEnv);
|
||||||
$sEnv = $sSwitchEnv;
|
$sEnv = $sSwitchEnv;
|
||||||
$bAllowCache = false;
|
$bAllowCache = false;
|
||||||
// Reset the opcache since otherwise the PHP "model" files may still be cached !!
|
// Reset the opcache since otherwise the PHP "model" files may still be cached !!
|
||||||
if (function_exists('opcache_reset'))
|
if (function_exists('opcache_reset')) {
|
||||||
{
|
// Zend opcode cache
|
||||||
// Zend opcode cache
|
opcache_reset();
|
||||||
opcache_reset();
|
}
|
||||||
}
|
if (function_exists('apc_clear_cache')) {
|
||||||
if (function_exists('apc_clear_cache'))
|
// APC(u) cache
|
||||||
{
|
apc_clear_cache();
|
||||||
// APC(u) cache
|
}
|
||||||
apc_clear_cache();
|
|
||||||
}
|
|
||||||
// TODO: reset the credentials as well ??
|
// TODO: reset the credentials as well ??
|
||||||
}
|
} elseif (Session::IsSet('itop_env')) {
|
||||||
else if (Session::IsSet('itop_env'))
|
|
||||||
{
|
|
||||||
$sEnv = Session::Get('itop_env');
|
$sEnv = Session::Get('itop_env');
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sEnv = ITOP_DEFAULT_ENV;
|
$sEnv = ITOP_DEFAULT_ENV;
|
||||||
Session::Set('itop_env', ITOP_DEFAULT_ENV);
|
Session::Set('itop_env', ITOP_DEFAULT_ENV);
|
||||||
}
|
}
|
||||||
$sConfigFile = APPCONF.$sEnv.'/'.ITOP_CONFIG_FILE;
|
$sConfigFile = APPCONF.$sEnv.'/'.ITOP_CONFIG_FILE;
|
||||||
try {
|
try {
|
||||||
MetaModel::Startup($sConfigFile, false /* $bModelOnly */, $bAllowCache, false /* $bTraceSourceFiles */, $sEnv);
|
MetaModel::Startup($sConfigFile, false /* $bModelOnly */, $bAllowCache, false /* $bTraceSourceFiles */, $sEnv);
|
||||||
|
} catch (MySQLException $e) {
|
||||||
|
IssueLog::Debug($e->getMessage());
|
||||||
|
throw new MySQLException('Could not connect to the DB server', []);
|
||||||
}
|
}
|
||||||
catch (MySQLException $e) {
|
|
||||||
IssueLog::Debug($e->getMessage());
|
|
||||||
throw new MySQLException('Could not connect to the DB server', []);
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2024 Combodo SAS
|
* Copyright (C) 2013-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
@@ -30,12 +31,12 @@ class DisplayTemplate
|
|||||||
{
|
{
|
||||||
protected $m_sTemplate;
|
protected $m_sTemplate;
|
||||||
protected $m_aTags;
|
protected $m_aTags;
|
||||||
static protected $iBlockCount = 0;
|
protected static $iBlockCount = 0;
|
||||||
|
|
||||||
public function __construct($sTemplate)
|
public function __construct($sTemplate)
|
||||||
{
|
{
|
||||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod();
|
DeprecatedCallsLog::NotifyDeprecatedPhpMethod();
|
||||||
$this->m_aTags = array(
|
$this->m_aTags = [
|
||||||
'itopblock',
|
'itopblock',
|
||||||
'itopcheck',
|
'itopcheck',
|
||||||
'itoptabs',
|
'itoptabs',
|
||||||
@@ -43,11 +44,11 @@ class DisplayTemplate
|
|||||||
'itoptoggle',
|
'itoptoggle',
|
||||||
'itopstring',
|
'itopstring',
|
||||||
'sqlblock',
|
'sqlblock',
|
||||||
);
|
];
|
||||||
$this->m_sTemplate = $sTemplate;
|
$this->m_sTemplate = $sTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Render(WebPage $oPage, $aParams = array())
|
public function Render(WebPage $oPage, $aParams = [])
|
||||||
{
|
{
|
||||||
$this->m_sTemplate = MetaModel::ApplyParams($this->m_sTemplate, $aParams);
|
$this->m_sTemplate = MetaModel::ApplyParams($this->m_sTemplate, $aParams);
|
||||||
$iStart = 0;
|
$iStart = 0;
|
||||||
@@ -55,70 +56,55 @@ class DisplayTemplate
|
|||||||
$iCount = 0;
|
$iCount = 0;
|
||||||
$iBeforeTagPos = $iStart;
|
$iBeforeTagPos = $iStart;
|
||||||
$iAfterTagPos = $iStart;
|
$iAfterTagPos = $iStart;
|
||||||
while($sTag = $this->GetNextTag($iStart, $iEnd))
|
while ($sTag = $this->GetNextTag($iStart, $iEnd)) {
|
||||||
{
|
|
||||||
$sContent = $this->GetTagContent($sTag, $iStart, $iEnd);
|
$sContent = $this->GetTagContent($sTag, $iStart, $iEnd);
|
||||||
$iAfterTagPos = $iEnd + strlen('</'.$sTag.'>');
|
$iAfterTagPos = $iEnd + strlen('</'.$sTag.'>');
|
||||||
$sOuterTag = substr($this->m_sTemplate, $iStart, $iAfterTagPos - $iStart);
|
$sOuterTag = substr($this->m_sTemplate, $iStart, $iAfterTagPos - $iStart);
|
||||||
$oPage->add(substr($this->m_sTemplate, $iBeforeTagPos, $iStart - $iBeforeTagPos));
|
$oPage->add(substr($this->m_sTemplate, $iBeforeTagPos, $iStart - $iBeforeTagPos));
|
||||||
if ($sTag == DisplayBlock::TAG_BLOCK)
|
if ($sTag == DisplayBlock::TAG_BLOCK) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
$oBlock = DisplayBlock::FromTemplate($sOuterTag);
|
$oBlock = DisplayBlock::FromTemplate($sOuterTag);
|
||||||
if (is_object($oBlock))
|
if (is_object($oBlock)) {
|
||||||
{
|
|
||||||
$oBlock->Display($oPage, 'block_'.self::$iBlockCount, $aParams);
|
$oBlock->Display($oPage, 'block_'.self::$iBlockCount, $aParams);
|
||||||
}
|
}
|
||||||
}
|
} catch (OQLException $e) {
|
||||||
catch(OQLException $e)
|
|
||||||
{
|
|
||||||
$oPage->p('Error in template (please contact your administrator) - Invalid query<!--'.$sOuterTag.'-->');
|
$oPage->p('Error in template (please contact your administrator) - Invalid query<!--'.$sOuterTag.'-->');
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch(Exception $e)
|
|
||||||
{
|
|
||||||
$oPage->p('Error in template (please contact your administrator)<!--'.$e->getMessage().'--><!--'.$sOuterTag.'-->');
|
$oPage->p('Error in template (please contact your administrator)<!--'.$e->getMessage().'--><!--'.$sOuterTag.'-->');
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$iBlockCount++;
|
self::$iBlockCount++;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aAttributes = $this->GetTagAttributes($sTag, $iStart, $iEnd);
|
$aAttributes = $this->GetTagAttributes($sTag, $iStart, $iEnd);
|
||||||
//$oPage->p("Tag: $sTag - ($iStart, $iEnd)");
|
//$oPage->p("Tag: $sTag - ($iStart, $iEnd)");
|
||||||
$this->RenderTag($oPage, $sTag, $aAttributes, $sContent);
|
$this->RenderTag($oPage, $sTag, $aAttributes, $sContent);
|
||||||
|
|
||||||
}
|
}
|
||||||
$iAfterTagPos = $iEnd + strlen('</'.$sTag.'>');
|
$iAfterTagPos = $iEnd + strlen('</'.$sTag.'>');
|
||||||
$iBeforeTagPos = $iAfterTagPos;
|
$iBeforeTagPos = $iAfterTagPos;
|
||||||
$iStart = $iEnd;
|
$iStart = $iEnd;
|
||||||
$iEnd = strlen($this->m_sTemplate);
|
$iEnd = strlen($this->m_sTemplate);
|
||||||
$iCount++;
|
$iCount++;
|
||||||
}
|
}
|
||||||
$oPage->add(substr($this->m_sTemplate, $iAfterTagPos));
|
$oPage->add(substr($this->m_sTemplate, $iAfterTagPos));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetNextTag(&$iStartPos, &$iEndPos)
|
public function GetNextTag(&$iStartPos, &$iEndPos)
|
||||||
{
|
{
|
||||||
$iChunkStartPos = $iStartPos;
|
$iChunkStartPos = $iStartPos;
|
||||||
$sNextTag = null;
|
$sNextTag = null;
|
||||||
$iStartPos = $iEndPos;
|
$iStartPos = $iEndPos;
|
||||||
foreach($this->m_aTags as $sTag)
|
foreach ($this->m_aTags as $sTag) {
|
||||||
{
|
|
||||||
// Search for the opening tag
|
// Search for the opening tag
|
||||||
$iOpeningPos = stripos($this->m_sTemplate, '<'.$sTag.' ', $iChunkStartPos);
|
$iOpeningPos = stripos($this->m_sTemplate, '<'.$sTag.' ', $iChunkStartPos);
|
||||||
if ($iOpeningPos === false)
|
if ($iOpeningPos === false) {
|
||||||
{
|
|
||||||
$iOpeningPos = stripos($this->m_sTemplate, '<'.$sTag.'>', $iChunkStartPos);
|
$iOpeningPos = stripos($this->m_sTemplate, '<'.$sTag.'>', $iChunkStartPos);
|
||||||
}
|
}
|
||||||
if ($iOpeningPos !== false)
|
if ($iOpeningPos !== false) {
|
||||||
{
|
|
||||||
$iClosingPos = stripos($this->m_sTemplate, '</'.$sTag.'>', $iOpeningPos);
|
$iClosingPos = stripos($this->m_sTemplate, '</'.$sTag.'>', $iOpeningPos);
|
||||||
}
|
}
|
||||||
if ( ($iOpeningPos !== false) && ($iClosingPos !== false))
|
if (($iOpeningPos !== false) && ($iClosingPos !== false)) {
|
||||||
{
|
if ($iOpeningPos < $iStartPos) {
|
||||||
if ($iOpeningPos < $iStartPos)
|
|
||||||
{
|
|
||||||
// This is the next tag
|
// This is the next tag
|
||||||
$iStartPos = $iOpeningPos;
|
$iStartPos = $iOpeningPos;
|
||||||
$iEndPos = $iClosingPos;
|
$iEndPos = $iClosingPos;
|
||||||
@@ -128,108 +114,100 @@ class DisplayTemplate
|
|||||||
}
|
}
|
||||||
return $sNextTag;
|
return $sNextTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetTagContent($sTag, $iStartPos, $iEndPos)
|
public function GetTagContent($sTag, $iStartPos, $iEndPos)
|
||||||
{
|
{
|
||||||
$sContent = "";
|
$sContent = "";
|
||||||
$iContentStart = strpos($this->m_sTemplate, '>', $iStartPos); // Content of tag start immediatly after the first closing bracket
|
$iContentStart = strpos($this->m_sTemplate, '>', $iStartPos); // Content of tag start immediatly after the first closing bracket
|
||||||
if ($iContentStart !== false)
|
if ($iContentStart !== false) {
|
||||||
{
|
$sContent = substr($this->m_sTemplate, 1 + $iContentStart, $iEndPos - $iContentStart - 1);
|
||||||
$sContent = substr($this->m_sTemplate, 1+$iContentStart, $iEndPos - $iContentStart - 1);
|
|
||||||
}
|
}
|
||||||
return $sContent;
|
return $sContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetTagAttributes($sTag, $iStartPos, $iEndPos)
|
public function GetTagAttributes($sTag, $iStartPos, $iEndPos)
|
||||||
{
|
{
|
||||||
$aAttr = array();
|
$aAttr = [];
|
||||||
$iAttrStart = strpos($this->m_sTemplate, ' ', $iStartPos); // Attributes start just after the first space
|
$iAttrStart = strpos($this->m_sTemplate, ' ', $iStartPos); // Attributes start just after the first space
|
||||||
$iAttrEnd = strpos($this->m_sTemplate, '>', $iStartPos); // Attributes end just before the first closing bracket
|
$iAttrEnd = strpos($this->m_sTemplate, '>', $iStartPos); // Attributes end just before the first closing bracket
|
||||||
if ( ($iAttrStart !== false) && ($iAttrEnd !== false) && ($iAttrEnd > $iAttrStart))
|
if (($iAttrStart !== false) && ($iAttrEnd !== false) && ($iAttrEnd > $iAttrStart)) {
|
||||||
{
|
$sAttributes = substr($this->m_sTemplate, 1 + $iAttrStart, $iAttrEnd - $iAttrStart - 1);
|
||||||
$sAttributes = substr($this->m_sTemplate, 1+$iAttrStart, $iAttrEnd - $iAttrStart - 1);
|
|
||||||
$aAttributes = explode(' ', $sAttributes);
|
$aAttributes = explode(' ', $sAttributes);
|
||||||
foreach($aAttributes as $sAttr)
|
foreach ($aAttributes as $sAttr) {
|
||||||
{
|
if (preg_match('/(.+) *= *"(.+)"$/', $sAttr, $aMatches)) {
|
||||||
if ( preg_match('/(.+) *= *"(.+)"$/', $sAttr, $aMatches) )
|
|
||||||
{
|
|
||||||
$aAttr[strtolower($aMatches[1])] = $aMatches[2];
|
$aAttr[strtolower($aMatches[1])] = $aMatches[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $aAttr;
|
return $aAttr;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function RenderTag($oPage, $sTag, $aAttributes, $sContent)
|
protected function RenderTag($oPage, $sTag, $aAttributes, $sContent)
|
||||||
{
|
{
|
||||||
static $iTabContainerCount = 0;
|
static $iTabContainerCount = 0;
|
||||||
switch($sTag)
|
switch ($sTag) {
|
||||||
{
|
|
||||||
case 'itoptabs':
|
case 'itoptabs':
|
||||||
$oPage->AddTabContainer('Tabs_'.$iTabContainerCount);
|
$oPage->AddTabContainer('Tabs_'.$iTabContainerCount);
|
||||||
$oPage->SetCurrentTabContainer('Tabs_'.$iTabContainerCount);
|
$oPage->SetCurrentTabContainer('Tabs_'.$iTabContainerCount);
|
||||||
$iTabContainerCount++;
|
$iTabContainerCount++;
|
||||||
//$oPage->p('Content:<pre>'.htmlentities($sContent, ENT_QUOTES, 'UTF-8').'</pre>');
|
//$oPage->p('Content:<pre>'.htmlentities($sContent, ENT_QUOTES, 'UTF-8').'</pre>');
|
||||||
$oTemplate = new DisplayTemplate($sContent);
|
$oTemplate = new DisplayTemplate($sContent);
|
||||||
$oTemplate->Render($oPage, array()); // no params to apply, they have already been applied
|
$oTemplate->Render($oPage, []); // no params to apply, they have already been applied
|
||||||
$oPage->SetCurrentTabContainer('');
|
$oPage->SetCurrentTabContainer('');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'itopcheck':
|
case 'itopcheck':
|
||||||
$sClassName = $aAttributes['class'];
|
$sClassName = $aAttributes['class'];
|
||||||
if (MetaModel::IsValidClass($sClassName) && UserRights::IsActionAllowed($sClassName, UR_ACTION_READ))
|
if (MetaModel::IsValidClass($sClassName) && UserRights::IsActionAllowed($sClassName, UR_ACTION_READ)) {
|
||||||
{
|
|
||||||
$oTemplate = new DisplayTemplate($sContent);
|
$oTemplate = new DisplayTemplate($sContent);
|
||||||
$oTemplate->Render($oPage, array()); // no params to apply, they have already been applied
|
$oTemplate->Render($oPage, []); // no params to apply, they have already been applied
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Leave a trace for those who'd like to understand why nothing is displayed
|
// Leave a trace for those who'd like to understand why nothing is displayed
|
||||||
$oPage->add("<!-- class $sClassName does not exist, skipping some part of the template -->\n");
|
$oPage->add("<!-- class $sClassName does not exist, skipping some part of the template -->\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'itoptab':
|
case 'itoptab':
|
||||||
$oPage->SetCurrentTab($aAttributes['name'], str_replace('_', ' ', $aAttributes['name']));
|
$oPage->SetCurrentTab($aAttributes['name'], str_replace('_', ' ', $aAttributes['name']));
|
||||||
$oTemplate = new DisplayTemplate($sContent);
|
$oTemplate = new DisplayTemplate($sContent);
|
||||||
$oTemplate->Render($oPage, array()); // no params to apply, they have already been applied
|
$oTemplate->Render($oPage, []); // no params to apply, they have already been applied
|
||||||
//$oPage->p('iTop Tab Content:<pre>'.htmlentities($sContent, ENT_QUOTES, 'UTF-8').'</pre>');
|
//$oPage->p('iTop Tab Content:<pre>'.htmlentities($sContent, ENT_QUOTES, 'UTF-8').'</pre>');
|
||||||
$oPage->SetCurrentTab('');
|
$oPage->SetCurrentTab('');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'itoptoggle':
|
case 'itoptoggle':
|
||||||
$sName = isset($aAttributes['name']) ? $aAttributes['name'] : 'Tagada';
|
$sName = isset($aAttributes['name']) ? $aAttributes['name'] : 'Tagada';
|
||||||
$bOpen = isset($aAttributes['open']) ? $aAttributes['open'] : true;
|
$bOpen = isset($aAttributes['open']) ? $aAttributes['open'] : true;
|
||||||
$oPage->StartCollapsibleSection(Dict::S($sName), $bOpen);
|
$oPage->StartCollapsibleSection(Dict::S($sName), $bOpen);
|
||||||
$oTemplate = new DisplayTemplate($sContent);
|
$oTemplate = new DisplayTemplate($sContent);
|
||||||
$oTemplate->Render($oPage, array()); // no params to apply, they have already been applied
|
$oTemplate->Render($oPage, []); // no params to apply, they have already been applied
|
||||||
//$oPage->p('iTop Tab Content:<pre>'.htmlentities($sContent, ENT_QUOTES, 'UTF-8').'</pre>');
|
//$oPage->p('iTop Tab Content:<pre>'.htmlentities($sContent, ENT_QUOTES, 'UTF-8').'</pre>');
|
||||||
$oPage->EndCollapsibleSection();
|
$oPage->EndCollapsibleSection();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'itopstring':
|
case 'itopstring':
|
||||||
$oPage->add(Dict::S($sContent));
|
$oPage->add(Dict::S($sContent));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlblock':
|
case 'sqlblock':
|
||||||
$oBlock = SqlBlock::FromTemplate($sContent);
|
$oBlock = SqlBlock::FromTemplate($sContent);
|
||||||
$oBlock->RenderContent($oPage);
|
$oBlock->RenderContent($oPage);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'itopblock': // No longer used, handled by DisplayBlock::FromTemplate see above
|
case 'itopblock': // No longer used, handled by DisplayBlock::FromTemplate see above
|
||||||
$oPage->add("<!-- Application Error: should be handled by DisplayBlock::FromTemplate -->");
|
$oPage->add("<!-- Application Error: should be handled by DisplayBlock::FromTemplate -->");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Unknown tag, just ignore it or now -- output an HTML comment
|
// Unknown tag, just ignore it or now -- output an HTML comment
|
||||||
$oPage->add("<!-- unsupported tag: $sTag -->");
|
$oPage->add("<!-- unsupported tag: $sTag -->");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit test
|
* Unit test
|
||||||
*/
|
*/
|
||||||
static public function UnitTest()
|
public static function UnitTest()
|
||||||
{
|
{
|
||||||
require_once(APPROOT.'/application/startup.inc.php');
|
require_once(APPROOT.'/application/startup.inc.php');
|
||||||
|
|
||||||
@@ -250,11 +228,11 @@ class DisplayTemplate
|
|||||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT Document AS d JOIN lnkDocumentToCI as l ON l.document_id = d.id WHERE l.ci_id = $id$)</itopblock>
|
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT Document AS d JOIN lnkDocumentToCI as l ON l.document_id = d.id WHERE l.ci_id = $id$)</itopblock>
|
||||||
</itoptab>
|
</itoptab>
|
||||||
</itoptabs>';
|
</itoptabs>';
|
||||||
|
|
||||||
$oPage = new iTopWebPage('Unit Test');
|
$oPage = new iTopWebPage('Unit Test');
|
||||||
//$oPage->add("Template content: <pre>".htmlentities($sTemplate, ENT_QUOTES, 'UTF-8')."</pre>\n");
|
//$oPage->add("Template content: <pre>".htmlentities($sTemplate, ENT_QUOTES, 'UTF-8')."</pre>\n");
|
||||||
$oTemplate = new DisplayTemplate($sTemplate);
|
$oTemplate = new DisplayTemplate($sTemplate);
|
||||||
$oTemplate->Render($oPage, array('class'=>'Network device','pkey'=> 271, 'name' => 'deliversw01.mecanorama.fr', 'org_id' => 3));
|
$oTemplate->Render($oPage, ['class' => 'Network device','pkey' => 271, 'name' => 'deliversw01.mecanorama.fr', 'org_id' => 3]);
|
||||||
$oPage->output();
|
$oPage->output();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,89 +253,68 @@ class ObjectDetailsTemplate extends DisplayTemplate
|
|||||||
$this->m_oObj = $oObj;
|
$this->m_oObj = $oObj;
|
||||||
$this->m_sPrefix = $sFormPrefix;
|
$this->m_sPrefix = $sFormPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Render(WebPage $oPage, $aParams = array(), $bEditMode = false)
|
public function Render(WebPage $oPage, $aParams = [], $bEditMode = false)
|
||||||
{
|
{
|
||||||
$sStateAttCode = MetaModel :: GetStateAttributeCode(get_class($this->m_oObj));
|
$sStateAttCode = MetaModel::GetStateAttributeCode(get_class($this->m_oObj));
|
||||||
$aTemplateFields = array();
|
$aTemplateFields = [];
|
||||||
preg_match_all('/\\$this->([a-z0-9_]+)\\$/', $this->m_sTemplate, $aMatches);
|
preg_match_all('/\\$this->([a-z0-9_]+)\\$/', $this->m_sTemplate, $aMatches);
|
||||||
foreach ($aMatches[1] as $sAttCode)
|
foreach ($aMatches[1] as $sAttCode) {
|
||||||
{
|
if (MetaModel::IsValidAttCode(get_class($this->m_oObj), $sAttCode)) {
|
||||||
if (MetaModel::IsValidAttCode(get_class($this->m_oObj), $sAttCode))
|
|
||||||
{
|
|
||||||
$aTemplateFields[] = $sAttCode;
|
$aTemplateFields[] = $sAttCode;
|
||||||
}
|
} else {
|
||||||
else
|
$aParams['this->'.$sAttCode] = "<!--Unknown attribute: $sAttCode-->";
|
||||||
{
|
|
||||||
$aParams['this->'.$sAttCode] = "<!--Unknown attribute: $sAttCode-->";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
preg_match_all('/\\$this->field\\(([a-z0-9_]+)\\)\\$/', $this->m_sTemplate, $aMatches);
|
preg_match_all('/\\$this->field\\(([a-z0-9_]+)\\)\\$/', $this->m_sTemplate, $aMatches);
|
||||||
foreach ($aMatches[1] as $sAttCode)
|
foreach ($aMatches[1] as $sAttCode) {
|
||||||
{
|
if (MetaModel::IsValidAttCode(get_class($this->m_oObj), $sAttCode)) {
|
||||||
if (MetaModel::IsValidAttCode(get_class($this->m_oObj), $sAttCode))
|
|
||||||
{
|
|
||||||
$aTemplateFields[] = $sAttCode;
|
$aTemplateFields[] = $sAttCode;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aParams['this->field('.$sAttCode.')'] = "<!--Unknown attribute: $sAttCode-->";
|
$aParams['this->field('.$sAttCode.')'] = "<!--Unknown attribute: $sAttCode-->";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aFieldsComments = (isset($aParams['fieldsComments'])) ? $aParams['fieldsComments'] : array();
|
$aFieldsComments = (isset($aParams['fieldsComments'])) ? $aParams['fieldsComments'] : [];
|
||||||
$aFieldsMap = array();
|
$aFieldsMap = [];
|
||||||
|
|
||||||
$sClass = get_class($this->m_oObj);
|
$sClass = get_class($this->m_oObj);
|
||||||
// Renders the fields used in the template
|
// Renders the fields used in the template
|
||||||
foreach(MetaModel::ListAttributeDefs(get_class($this->m_oObj)) as $sAttCode => $oAttDef)
|
foreach (MetaModel::ListAttributeDefs(get_class($this->m_oObj)) as $sAttCode => $oAttDef) {
|
||||||
{
|
|
||||||
$aParams['this->label('.$sAttCode.')'] = $oAttDef->GetLabel();
|
$aParams['this->label('.$sAttCode.')'] = $oAttDef->GetLabel();
|
||||||
$aParams['this->comments('.$sAttCode.')'] = isset($aFieldsComments[$sAttCode]) ? $aFieldsComments[$sAttCode] : '';
|
$aParams['this->comments('.$sAttCode.')'] = isset($aFieldsComments[$sAttCode]) ? $aFieldsComments[$sAttCode] : '';
|
||||||
$iInputId = '2_'.$sAttCode; // TODO: generate a real/unique prefix...
|
$iInputId = '2_'.$sAttCode; // TODO: generate a real/unique prefix...
|
||||||
if (in_array($sAttCode, $aTemplateFields))
|
if (in_array($sAttCode, $aTemplateFields)) {
|
||||||
{
|
if ($this->m_oObj->IsNew()) {
|
||||||
if ($this->m_oObj->IsNew())
|
|
||||||
{
|
|
||||||
$iFlags = $this->m_oObj->GetInitialStateAttributeFlags($sAttCode);
|
$iFlags = $this->m_oObj->GetInitialStateAttributeFlags($sAttCode);
|
||||||
|
} else {
|
||||||
|
$iFlags = $this->m_oObj->GetAttributeFlags($sAttCode);
|
||||||
}
|
}
|
||||||
else
|
if (($iFlags & OPT_ATT_MANDATORY) && $this->m_oObj->IsNew()) {
|
||||||
{
|
|
||||||
$iFlags = $this->m_oObj->GetAttributeFlags($sAttCode);
|
|
||||||
}
|
|
||||||
if (($iFlags & OPT_ATT_MANDATORY) && $this->m_oObj->IsNew())
|
|
||||||
{
|
|
||||||
$iFlags = $iFlags & ~OPT_ATT_READONLY; // Mandatory fields cannot be read-only when creating an object
|
$iFlags = $iFlags & ~OPT_ATT_READONLY; // Mandatory fields cannot be read-only when creating an object
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!$oAttDef->IsWritable()) || ($sStateAttCode == $sAttCode))
|
if ((!$oAttDef->IsWritable()) || ($sStateAttCode == $sAttCode)) {
|
||||||
{
|
|
||||||
$iFlags = $iFlags | OPT_ATT_READONLY;
|
$iFlags = $iFlags | OPT_ATT_READONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($iFlags & OPT_ATT_HIDDEN)
|
if ($iFlags & OPT_ATT_HIDDEN) {
|
||||||
{
|
|
||||||
$aParams['this->label('.$sAttCode.')'] = '';
|
$aParams['this->label('.$sAttCode.')'] = '';
|
||||||
$aParams['this->field('.$sAttCode.')'] = '';
|
$aParams['this->field('.$sAttCode.')'] = '';
|
||||||
$aParams['this->comments('.$sAttCode.')'] = '';
|
$aParams['this->comments('.$sAttCode.')'] = '';
|
||||||
$aParams['this->'.$sAttCode] = '';
|
$aParams['this->'.$sAttCode] = '';
|
||||||
}
|
} else {
|
||||||
else
|
if ($bEditMode && ($iFlags & (OPT_ATT_READONLY | OPT_ATT_SLAVE))) {
|
||||||
{
|
|
||||||
if ($bEditMode && ($iFlags & (OPT_ATT_READONLY|OPT_ATT_SLAVE)))
|
|
||||||
{
|
|
||||||
// Check if the attribute is not read-only because of a synchro...
|
// Check if the attribute is not read-only because of a synchro...
|
||||||
$aReasons = array();
|
$aReasons = [];
|
||||||
$sSynchroIcon = '';
|
$sSynchroIcon = '';
|
||||||
if ($iFlags & OPT_ATT_SLAVE)
|
if ($iFlags & OPT_ATT_SLAVE) {
|
||||||
{
|
|
||||||
$iSynchroFlags = $this->m_oObj->GetSynchroReplicaFlags($sAttCode, $aReasons);
|
$iSynchroFlags = $this->m_oObj->GetSynchroReplicaFlags($sAttCode, $aReasons);
|
||||||
$sAppRooturl = utils::GetAbsoluteUrlAppRoot();
|
$sAppRooturl = utils::GetAbsoluteUrlAppRoot();
|
||||||
$sSynchroIcon = " <img id=\"synchro_$iInputId\" src=\"{$sAppRooturl}images/transp-lock.png\" style=\"vertical-align:middle\"/>";
|
$sSynchroIcon = " <img id=\"synchro_$iInputId\" src=\"{$sAppRooturl}images/transp-lock.png\" style=\"vertical-align:middle\"/>";
|
||||||
$sTip = '';
|
$sTip = '';
|
||||||
foreach($aReasons as $aRow)
|
foreach ($aReasons as $aRow) {
|
||||||
{
|
|
||||||
$sDescription = utils::EscapeHtml($aRow['description']);
|
$sDescription = utils::EscapeHtml($aRow['description']);
|
||||||
$sDescription = str_replace(array("\r\n", "\n"), "<br/>", $sDescription);
|
$sDescription = str_replace(["\r\n", "\n"], "<br/>", $sDescription);
|
||||||
$sTip .= "<div class='synchro-source'>";
|
$sTip .= "<div class='synchro-source'>";
|
||||||
$sTip .= "<div class='synchro-source-title'>Synchronized with {$aRow['name']}</div>";
|
$sTip .= "<div class='synchro-source-title'>Synchronized with {$aRow['name']}</div>";
|
||||||
$sTip .= "<div class='synchro-source-description'>$sDescription</div>";
|
$sTip .= "<div class='synchro-source-description'>$sDescription</div>";
|
||||||
@@ -371,46 +328,43 @@ class ObjectDetailsTemplate extends DisplayTemplate
|
|||||||
$aFieldsMap[$sAttCode] = $iInputId;
|
$aFieldsMap[$sAttCode] = $iInputId;
|
||||||
$aParams['this->comments('.$sAttCode.')'] = $sSynchroIcon;
|
$aParams['this->comments('.$sAttCode.')'] = $sSynchroIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($bEditMode && !($iFlags & OPT_ATT_READONLY)) //TODO: check the data synchro status...
|
if ($bEditMode && !($iFlags & OPT_ATT_READONLY)) { //TODO: check the data synchro status...
|
||||||
{
|
$aParams['this->field('.$sAttCode.')'] = "<span id=\"field_{$iInputId}\">".$this->m_oObj->GetFormElementForField(
|
||||||
$aParams['this->field('.$sAttCode.')'] = "<span id=\"field_{$iInputId}\">".$this->m_oObj->GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef,
|
$oPage,
|
||||||
$this->m_oObj->Get($sAttCode),
|
$sClass,
|
||||||
$this->m_oObj->GetEditValue($sAttCode),
|
$sAttCode,
|
||||||
$iInputId, // InputID
|
$oAttDef,
|
||||||
'',
|
$this->m_oObj->Get($sAttCode),
|
||||||
$iFlags,
|
$this->m_oObj->GetEditValue($sAttCode),
|
||||||
array('this' => $this->m_oObj) // aArgs
|
$iInputId, // InputID
|
||||||
).'</span>';
|
'',
|
||||||
$aFieldsMap[$sAttCode] = $iInputId;
|
$iFlags,
|
||||||
}
|
['this' => $this->m_oObj] // aArgs
|
||||||
else
|
).'</span>';
|
||||||
{
|
$aFieldsMap[$sAttCode] = $iInputId;
|
||||||
|
} else {
|
||||||
$aParams['this->field('.$sAttCode.')'] = $this->m_oObj->GetAsHTML($sAttCode);
|
$aParams['this->field('.$sAttCode.')'] = $this->m_oObj->GetAsHTML($sAttCode);
|
||||||
}
|
}
|
||||||
$aParams['this->'.$sAttCode] = "<table class=\"field\"><tr><td class=\"label\">".$aParams['this->label('.$sAttCode.')'].":</td><td>".$aParams['this->field('.$sAttCode.')']."</td><td>".$aParams['this->comments('.$sAttCode.')']."</td></tr></table>";
|
$aParams['this->'.$sAttCode] = "<table class=\"field\"><tr><td class=\"label\">".$aParams['this->label('.$sAttCode.')'].":</td><td>".$aParams['this->field('.$sAttCode.')']."</td><td>".$aParams['this->comments('.$sAttCode.')']."</td></tr></table>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renders the PlugIns used in the template
|
// Renders the PlugIns used in the template
|
||||||
preg_match_all('/\\$PlugIn:([A-Za-z0-9_]+)->properties\\(\\)\\$/', $this->m_sTemplate, $aMatches);
|
preg_match_all('/\\$PlugIn:([A-Za-z0-9_]+)->properties\\(\\)\\$/', $this->m_sTemplate, $aMatches);
|
||||||
$aPlugInProperties = $aMatches[1];
|
$aPlugInProperties = $aMatches[1];
|
||||||
foreach($aPlugInProperties as $sPlugInClass)
|
foreach ($aPlugInProperties as $sPlugInClass) {
|
||||||
{
|
|
||||||
/** @var \iApplicationUIExtension $oInstance */
|
/** @var \iApplicationUIExtension $oInstance */
|
||||||
$oInstance = MetaModel::GetPlugins('iApplicationUIExtension', $sPlugInClass);
|
$oInstance = MetaModel::GetPlugins('iApplicationUIExtension', $sPlugInClass);
|
||||||
if ($oInstance != null) // Safety check...
|
if ($oInstance != null) { // Safety check...
|
||||||
{
|
|
||||||
$offset = $oPage->start_capture();
|
$offset = $oPage->start_capture();
|
||||||
$oInstance->OnDisplayProperties($this->m_oObj, $oPage, $bEditMode);
|
$oInstance->OnDisplayProperties($this->m_oObj, $oPage, $bEditMode);
|
||||||
$sContent = $oPage->end_capture($offset);
|
$sContent = $oPage->end_capture($offset);
|
||||||
$aParams["PlugIn:{$sPlugInClass}->properties()"]= $sContent;
|
$aParams["PlugIn:{$sPlugInClass}->properties()"] = $sContent;
|
||||||
|
} else {
|
||||||
|
$aParams["PlugIn:{$sPlugInClass}->properties()"] = "Missing PlugIn: $sPlugInClass";
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
$aParams["PlugIn:{$sPlugInClass}->properties()"]= "Missing PlugIn: $sPlugInClass";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$offset = $oPage->start_capture();
|
$offset = $oPage->start_capture();
|
||||||
@@ -424,4 +378,3 @@ class ObjectDetailsTemplate extends DisplayTemplate
|
|||||||
}
|
}
|
||||||
|
|
||||||
//DisplayTemplate::UnitTest();
|
//DisplayTemplate::UnitTest();
|
||||||
?>
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2024 Combodo SAS
|
* Copyright (C) 2013-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
@@ -25,7 +26,7 @@
|
|||||||
*/
|
*/
|
||||||
class ThemeHandler
|
class ThemeHandler
|
||||||
{
|
{
|
||||||
const IMAGE_EXTENSIONS = ['png', 'gif', 'jpg', 'jpeg'];
|
public const IMAGE_EXTENSIONS = ['png', 'gif', 'jpg', 'jpeg'];
|
||||||
|
|
||||||
/** @var \CompileCSSService */
|
/** @var \CompileCSSService */
|
||||||
private static $oCompileCSSService;
|
private static $oCompileCSSService;
|
||||||
@@ -50,7 +51,7 @@ class ThemeHandler
|
|||||||
'imports' => [],
|
'imports' => [],
|
||||||
'stylesheets' => [
|
'stylesheets' => [
|
||||||
'main' => '../css/backoffice/main.scss',
|
'main' => '../css/backoffice/main.scss',
|
||||||
]
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -75,8 +76,7 @@ class ThemeHandler
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$sThemeId = utils::GetConfig()->Get('backoffice_default_theme');
|
$sThemeId = utils::GetConfig()->Get('backoffice_default_theme');
|
||||||
}
|
} catch (CoreException $oCompileException) {
|
||||||
catch (CoreException $oCompileException) {
|
|
||||||
// Fallback on our default theme in case the config. is not available yet
|
// Fallback on our default theme in case the config. is not available yet
|
||||||
$aDefaultTheme = ThemeHandler::GetDefaultThemeInformation();
|
$aDefaultTheme = ThemeHandler::GetDefaultThemeInformation();
|
||||||
$sThemeId = $aDefaultTheme['name'];
|
$sThemeId = $aDefaultTheme['name'];
|
||||||
@@ -97,8 +97,7 @@ class ThemeHandler
|
|||||||
if (true === utils::GetConfig()->Get('user_preferences.allow_backoffice_theme_override')) {
|
if (true === utils::GetConfig()->Get('user_preferences.allow_backoffice_theme_override')) {
|
||||||
$sThemeId = appUserPreferences::GetPref('backoffice_theme', null);
|
$sThemeId = appUserPreferences::GetPref('backoffice_theme', null);
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $oException) {
|
||||||
catch (Exception $oException) {
|
|
||||||
// Do nothing, already handled by $sThemeId null by default
|
// Do nothing, already handled by $sThemeId null by default
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,8 +212,7 @@ class ThemeHandler
|
|||||||
if (static::ShouldThemeSignatureCheckBeForced($sThemeId)) {
|
if (static::ShouldThemeSignatureCheckBeForced($sThemeId)) {
|
||||||
static::CompileTheme($sThemeId);
|
static::CompileTheme($sThemeId);
|
||||||
}
|
}
|
||||||
}
|
} catch (CoreException $oCompileException) {
|
||||||
catch (CoreException $oCompileException) {
|
|
||||||
// Fallback on our default theme (should always be compilable) in case the previous theme doesn't exists
|
// Fallback on our default theme (should always be compilable) in case the previous theme doesn't exists
|
||||||
$aDefaultTheme = ThemeHandler::GetDefaultThemeInformation();
|
$aDefaultTheme = ThemeHandler::GetDefaultThemeInformation();
|
||||||
$sThemeId = $aDefaultTheme['name'];
|
$sThemeId = $aDefaultTheme['name'];
|
||||||
@@ -270,13 +268,16 @@ class ThemeHandler
|
|||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @return boolean: indicate whether theme compilation occured
|
* @return boolean: indicate whether theme compilation occured
|
||||||
*/
|
*/
|
||||||
public static function CompileTheme($sThemeId, $bSetup=false, $sSetupCompilationTimestamp="", $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null) {
|
public static function CompileTheme($sThemeId, $bSetup = false, $sSetupCompilationTimestamp = "", $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null)
|
||||||
|
{
|
||||||
if ($sSetupCompilationTimestamp === "") {
|
if ($sSetupCompilationTimestamp === "") {
|
||||||
$sSetupCompilationTimestamp = microtime(true);
|
$sSetupCompilationTimestamp = microtime(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sSetupCompilationTimestampInSecunds = (strpos($sSetupCompilationTimestamp, '.') !== false) ? explode('.',
|
$sSetupCompilationTimestampInSecunds = (strpos($sSetupCompilationTimestamp, '.') !== false) ? explode(
|
||||||
$sSetupCompilationTimestamp)[0] : $sSetupCompilationTimestamp;
|
'.',
|
||||||
|
$sSetupCompilationTimestamp
|
||||||
|
)[0] : $sSetupCompilationTimestamp;
|
||||||
|
|
||||||
$sEnv = APPROOT.'env-'.utils::GetCurrentEnvironment().'/';
|
$sEnv = APPROOT.'env-'.utils::GetCurrentEnvironment().'/';
|
||||||
|
|
||||||
@@ -329,7 +330,7 @@ class ThemeHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($oFindStylesheetObject->GetStylesheetFileURIs() as $sStylesheet){
|
foreach ($oFindStylesheetObject->GetStylesheetFileURIs() as $sStylesheet) {
|
||||||
$sTmpThemeScssContent .= '@import "'.$sStylesheet.'";'."\n";
|
$sTmpThemeScssContent .= '@import "'.$sStylesheet.'";'."\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,11 +342,9 @@ class ThemeHandler
|
|||||||
|
|
||||||
$iStyleLastModified = $oFindStylesheetObject->GetLastModified();
|
$iStyleLastModified = $oFindStylesheetObject->GetLastModified();
|
||||||
|
|
||||||
$aIncludedImages=static::GetIncludedImages($aThemeParametersWithVersion, $oFindStylesheetObject->GetAllStylesheetPaths(), $sThemeId);
|
$aIncludedImages = static::GetIncludedImages($aThemeParametersWithVersion, $oFindStylesheetObject->GetAllStylesheetPaths(), $sThemeId);
|
||||||
foreach ($aIncludedImages as $sImage)
|
foreach ($aIncludedImages as $sImage) {
|
||||||
{
|
if (is_file($sImage)) {
|
||||||
if (is_file($sImage))
|
|
||||||
{
|
|
||||||
$iStylesheetLastModified = @filemtime($sImage);
|
$iStylesheetLastModified = @filemtime($sImage);
|
||||||
$iStyleLastModified = $iStyleLastModified < $iStylesheetLastModified ? $iStylesheetLastModified : $iStyleLastModified;
|
$iStyleLastModified = $iStyleLastModified < $iStylesheetLastModified ? $iStylesheetLastModified : $iStyleLastModified;
|
||||||
}
|
}
|
||||||
@@ -354,34 +353,28 @@ class ThemeHandler
|
|||||||
// Checking if our compiled css is outdated
|
// Checking if our compiled css is outdated
|
||||||
$iFilemetime = @filemtime($sThemeCssPath);
|
$iFilemetime = @filemtime($sThemeCssPath);
|
||||||
$bFileExists = file_exists($sThemeCssPath);
|
$bFileExists = file_exists($sThemeCssPath);
|
||||||
$bVarSignatureChanged=false;
|
$bVarSignatureChanged = false;
|
||||||
if ($bFileExists && $bSetup)
|
if ($bFileExists && $bSetup) {
|
||||||
{
|
|
||||||
$sPrecompiledSignature = static::GetSignature($sThemeCssPath);
|
$sPrecompiledSignature = static::GetSignature($sThemeCssPath);
|
||||||
//check variable signature has changed which is independant from any file modification
|
//check variable signature has changed which is independant from any file modification
|
||||||
if (!empty($sPrecompiledSignature)){
|
if (!empty($sPrecompiledSignature)) {
|
||||||
$sPreviousVariableSignature = static::GetVarSignature($sPrecompiledSignature);
|
$sPreviousVariableSignature = static::GetVarSignature($sPrecompiledSignature);
|
||||||
$sCurrentVariableSignature = md5(json_encode($aThemeParameters['variables']));
|
$sCurrentVariableSignature = md5(json_encode($aThemeParameters['variables']));
|
||||||
$bVarSignatureChanged= ($sPreviousVariableSignature!==$sCurrentVariableSignature);
|
$bVarSignatureChanged = ($sPreviousVariableSignature !== $sCurrentVariableSignature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$bFileExists || $bVarSignatureChanged || (is_writable($sThemeFolderPath) && ($iFilemetime < $iStyleLastModified)))
|
if (!$bFileExists || $bVarSignatureChanged || (is_writable($sThemeFolderPath) && ($iFilemetime < $iStyleLastModified))) {
|
||||||
{
|
|
||||||
// Dates don't match. Second chance: check if the already compiled stylesheet exists and is consistent based on its signature
|
// Dates don't match. Second chance: check if the already compiled stylesheet exists and is consistent based on its signature
|
||||||
$sActualSignature = static::ComputeSignature($aThemeParameters, $aImportsPaths, $aIncludedImages);
|
$sActualSignature = static::ComputeSignature($aThemeParameters, $aImportsPaths, $aIncludedImages);
|
||||||
|
|
||||||
if ($bFileExists && !$bSetup)
|
if ($bFileExists && !$bSetup) {
|
||||||
{
|
|
||||||
$sPrecompiledSignature = static::GetSignature($sThemeCssPath);
|
$sPrecompiledSignature = static::GetSignature($sThemeCssPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($sPrecompiledSignature) && $sActualSignature == $sPrecompiledSignature)
|
if (!empty($sPrecompiledSignature) && $sActualSignature == $sPrecompiledSignature) {
|
||||||
{
|
|
||||||
touch($sThemeCssPath); // Stylesheet is up to date, mark it as more recent to speedup next time
|
touch($sThemeCssPath); // Stylesheet is up to date, mark it as more recent to speedup next time
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Alas, we really need to recompile
|
// Alas, we really need to recompile
|
||||||
// Add the signature to the generated CSS file so that the file can be used as a precompiled stylesheet if needed
|
// Add the signature to the generated CSS file so that the file can be used as a precompiled stylesheet if needed
|
||||||
$sSignatureComment =
|
$sSignatureComment =
|
||||||
@@ -393,14 +386,16 @@ $sActualSignature
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
CSS;
|
CSS;
|
||||||
if (!static::$oCompileCSSService)
|
if (!static::$oCompileCSSService) {
|
||||||
{
|
|
||||||
static::$oCompileCSSService = new CompileCSSService();
|
static::$oCompileCSSService = new CompileCSSService();
|
||||||
}
|
}
|
||||||
//store it again to change $version with latest compiled time
|
//store it again to change $version with latest compiled time
|
||||||
SetupLog::Info("Compiling theme $sThemeId...");
|
SetupLog::Info("Compiling theme $sThemeId...");
|
||||||
$sTmpThemeCssContent = static::$oCompileCSSService->CompileCSSFromSASS($sTmpThemeScssContent, $aImportsPaths,
|
$sTmpThemeCssContent = static::$oCompileCSSService->CompileCSSFromSASS(
|
||||||
$aThemeParametersWithVersion);
|
$sTmpThemeScssContent,
|
||||||
|
$aImportsPaths,
|
||||||
|
$aThemeParametersWithVersion
|
||||||
|
);
|
||||||
SetupLog::Info("$sThemeId theme compilation done.");
|
SetupLog::Info("$sThemeId theme compilation done.");
|
||||||
file_put_contents($sThemeFolderPath.'/theme-parameters.json', json_encode($aThemeParameters));
|
file_put_contents($sThemeFolderPath.'/theme-parameters.json', json_encode($aThemeParameters));
|
||||||
file_put_contents($sThemeCssPath, $sSignatureComment.$sTmpThemeCssContent);
|
file_put_contents($sThemeCssPath, $sSignatureComment.$sTmpThemeCssContent);
|
||||||
@@ -425,13 +420,14 @@ CSS;
|
|||||||
* @return string
|
* @return string
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function ComputeSignature($aThemeParameters, $aImportsPaths, $aIncludedImages) {
|
public static function ComputeSignature($aThemeParameters, $aImportsPaths, $aIncludedImages)
|
||||||
|
{
|
||||||
$aSignature = [
|
$aSignature = [
|
||||||
'variables' => md5(json_encode($aThemeParameters['variables'])),
|
'variables' => md5(json_encode($aThemeParameters['variables'])),
|
||||||
'stylesheets' => [],
|
'stylesheets' => [],
|
||||||
'variable_imports' => [],
|
'variable_imports' => [],
|
||||||
'images' => [],
|
'images' => [],
|
||||||
'utility_imports' => []
|
'utility_imports' => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
$oFindStylesheetObject = new FindStylesheetObject();
|
$oFindStylesheetObject = new FindStylesheetObject();
|
||||||
@@ -473,8 +469,7 @@ CSS;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($aIncludedImages as $sImage)
|
foreach ($aIncludedImages as $sImage) {
|
||||||
{
|
|
||||||
if (is_file($sImage)) {
|
if (is_file($sImage)) {
|
||||||
$sUri = str_replace(self::GetAppRootWithSlashes(), '', $sImage);
|
$sUri = str_replace(self::GetAppRootWithSlashes(), '', $sImage);
|
||||||
$aSignature['images'][$sUri] = md5_file($sImage);
|
$aSignature['images'][$sUri] = md5_file($sImage);
|
||||||
@@ -501,7 +496,7 @@ CSS;
|
|||||||
$aCompleteUrls = [];
|
$aCompleteUrls = [];
|
||||||
$aToCompleteUrls = [];
|
$aToCompleteUrls = [];
|
||||||
$aMissingVariables = [];
|
$aMissingVariables = [];
|
||||||
$aFoundVariables = ['version'=>''];
|
$aFoundVariables = ['version' => ''];
|
||||||
$aMap = [
|
$aMap = [
|
||||||
'aCompleteUrls' => $aCompleteUrls,
|
'aCompleteUrls' => $aCompleteUrls,
|
||||||
'aToCompleteUrls' => $aToCompleteUrls,
|
'aToCompleteUrls' => $aToCompleteUrls,
|
||||||
@@ -509,14 +504,11 @@ CSS;
|
|||||||
'aFoundVariables' => $aFoundVariables,
|
'aFoundVariables' => $aFoundVariables,
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($aStylesheetFiles as $sStylesheetFile)
|
foreach ($aStylesheetFiles as $sStylesheetFile) {
|
||||||
{
|
|
||||||
$aRes = static::GetAllUrlFromScss($aThemeParametersVariables, $sStylesheetFile);
|
$aRes = static::GetAllUrlFromScss($aThemeParametersVariables, $sStylesheetFile);
|
||||||
/** @var array $aVal */
|
/** @var array $aVal */
|
||||||
foreach($aMap as $key => $aVal)
|
foreach ($aMap as $key => $aVal) {
|
||||||
{
|
if (array_key_exists($key, $aMap)) {
|
||||||
if (array_key_exists($key, $aMap))
|
|
||||||
{
|
|
||||||
$aMap[$key] = array_merge($aVal, $aRes[$key]);
|
$aMap[$key] = array_merge($aVal, $aRes[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -525,17 +517,14 @@ CSS;
|
|||||||
$aMap = static::ResolveUncompleteUrlsFromScss($aMap, $aThemeParametersVariables, $aStylesheetFiles);
|
$aMap = static::ResolveUncompleteUrlsFromScss($aMap, $aThemeParametersVariables, $aStylesheetFiles);
|
||||||
$aImages = [];
|
$aImages = [];
|
||||||
|
|
||||||
foreach ($aMap ['aCompleteUrls'] as $sUri => $sUrl)
|
foreach ($aMap ['aCompleteUrls'] as $sUri => $sUrl) {
|
||||||
{
|
|
||||||
$sImg = $sUrl;
|
$sImg = $sUrl;
|
||||||
if (preg_match("/(.*)\?/", $sUrl, $aMatches))
|
if (preg_match("/(.*)\?/", $sUrl, $aMatches)) {
|
||||||
{
|
$sImg = $aMatches[1];
|
||||||
$sImg=$aMatches[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (static::HasImageExtension($sImg)
|
if (static::HasImageExtension($sImg)
|
||||||
&& ! array_key_exists($sImg, $aImages))
|
&& ! array_key_exists($sImg, $aImages)) {
|
||||||
{
|
|
||||||
$sFilePath = utils::RealPath($sImg, APPROOT);
|
$sFilePath = utils::RealPath($sImg, APPROOT);
|
||||||
if ($sFilePath !== false) {
|
if ($sFilePath !== false) {
|
||||||
$sFilePathWithSlashes = str_replace('\\', '/', $sFilePath);
|
$sFilePathWithSlashes = str_replace('\\', '/', $sFilePath);
|
||||||
@@ -566,8 +555,8 @@ CSS;
|
|||||||
*/
|
*/
|
||||||
public static function CanonicalizePath($path)
|
public static function CanonicalizePath($path)
|
||||||
{
|
{
|
||||||
$path = explode('/', str_replace('//','/', $path));
|
$path = explode('/', str_replace('//', '/', $path));
|
||||||
$stack = array();
|
$stack = [];
|
||||||
foreach ($path as $seg) {
|
foreach ($path as $seg) {
|
||||||
if ($seg == '..') {
|
if ($seg == '..') {
|
||||||
// Ignore this segment, remove last segment from stack
|
// Ignore this segment, remove last segment from stack
|
||||||
@@ -597,25 +586,23 @@ CSS;
|
|||||||
*/
|
*/
|
||||||
public static function ResolveUncompleteUrlsFromScss($aMap, $aThemeParametersVariables, $aStylesheetFile)
|
public static function ResolveUncompleteUrlsFromScss($aMap, $aThemeParametersVariables, $aStylesheetFile)
|
||||||
{
|
{
|
||||||
$sContent="";
|
$sContent = "";
|
||||||
foreach ($aStylesheetFile as $sStylesheetFile)
|
foreach ($aStylesheetFile as $sStylesheetFile) {
|
||||||
{
|
if (is_file($sStylesheetFile)) {
|
||||||
if (is_file($sStylesheetFile))
|
$sContent .= '\n'.file_get_contents($sStylesheetFile);
|
||||||
{
|
|
||||||
$sContent .= '\n' . file_get_contents($sStylesheetFile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$aMissingVariables=$aMap['aMissingVariables'];
|
$aMissingVariables = $aMap['aMissingVariables'];
|
||||||
$aFoundVariables=$aMap['aFoundVariables'];
|
$aFoundVariables = $aMap['aFoundVariables'];
|
||||||
$aToCompleteUrls=$aMap['aToCompleteUrls'];
|
$aToCompleteUrls = $aMap['aToCompleteUrls'];
|
||||||
$aCompleteUrls=$aMap['aCompleteUrls'];
|
$aCompleteUrls = $aMap['aCompleteUrls'];
|
||||||
list($aMissingVariables, $aFoundVariables) = static::FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent, true);
|
list($aMissingVariables, $aFoundVariables) = static::FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent, true);
|
||||||
list($aToCompleteUrls, $aCompleteUrls) = static::ResolveUrls($aFoundVariables, $aToCompleteUrls, $aCompleteUrls);
|
list($aToCompleteUrls, $aCompleteUrls) = static::ResolveUrls($aFoundVariables, $aToCompleteUrls, $aCompleteUrls);
|
||||||
$aMap['aMissingVariables']=$aMissingVariables;
|
$aMap['aMissingVariables'] = $aMissingVariables;
|
||||||
$aMap['aFoundVariables']=$aFoundVariables;
|
$aMap['aFoundVariables'] = $aFoundVariables;
|
||||||
$aMap['aToCompleteUrls']=$aToCompleteUrls;
|
$aMap['aToCompleteUrls'] = $aToCompleteUrls;
|
||||||
$aMap['aCompleteUrls']=$aCompleteUrls;
|
$aMap['aCompleteUrls'] = $aCompleteUrls;
|
||||||
return $aMap;
|
return $aMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -631,43 +618,29 @@ CSS;
|
|||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent, $bForceEmptyValueWhenNotFound=false)
|
public static function FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent, $bForceEmptyValueWhenNotFound = false)
|
||||||
{
|
{
|
||||||
$aNewMissingVars = [];
|
$aNewMissingVars = [];
|
||||||
if (!empty($aMissingVariables))
|
if (!empty($aMissingVariables)) {
|
||||||
{
|
foreach ($aMissingVariables as $var) {
|
||||||
foreach ($aMissingVariables as $var)
|
if (array_key_exists($var, $aThemeParametersVariables)) {
|
||||||
{
|
|
||||||
if (array_key_exists($var, $aThemeParametersVariables))
|
|
||||||
{
|
|
||||||
$aFoundVariables[$var] = $aThemeParametersVariables[$var];
|
$aFoundVariables[$var] = $aThemeParametersVariables[$var];
|
||||||
}
|
} else {
|
||||||
else
|
if (preg_match_all("/\\\$$var\s*:\s*[\"']{0,1}(.*)[\"']{0,1};/", $sContent, $aValues)) {
|
||||||
{
|
|
||||||
if (preg_match_all("/\\\$$var\s*:\s*[\"']{0,1}(.*)[\"']{0,1};/", $sContent, $aValues))
|
|
||||||
{
|
|
||||||
$sValue = $aValues[1][0];
|
$sValue = $aValues[1][0];
|
||||||
if (preg_match_all("/([^!]+)!/", $sValue, $aSubValues))
|
if (preg_match_all("/([^!]+)!/", $sValue, $aSubValues)) {
|
||||||
{
|
|
||||||
$sValue = trim($aSubValues[1][0], ' "\'');
|
$sValue = trim($aSubValues[1][0], ' "\'');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strpos($sValue, '$') === false)
|
if (strpos($sValue, '$') === false) {
|
||||||
{
|
|
||||||
$aFoundVariables[$var] = $sValue;
|
$aFoundVariables[$var] = $sValue;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
$aNewMissingVars[] = $var;
|
$aNewMissingVars[] = $var;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
if ($bForceEmptyValueWhenNotFound) {
|
||||||
{
|
|
||||||
if ($bForceEmptyValueWhenNotFound)
|
|
||||||
{
|
|
||||||
$aFoundVariables[$var] = '';
|
$aFoundVariables[$var] = '';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aNewMissingVars[] = $var;
|
$aNewMissingVars[] = $var;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -688,32 +661,23 @@ CSS;
|
|||||||
*/
|
*/
|
||||||
public static function ResolveUrls($aFoundVariables, array $aToCompleteUrls, array $aCompleteUrls)
|
public static function ResolveUrls($aFoundVariables, array $aToCompleteUrls, array $aCompleteUrls)
|
||||||
{
|
{
|
||||||
if (!empty($aFoundVariables))
|
if (!empty($aFoundVariables)) {
|
||||||
{
|
|
||||||
$aFoundVariablesWithEmptyValue = [];
|
$aFoundVariablesWithEmptyValue = [];
|
||||||
foreach ($aFoundVariables as $aFoundVariable => $sValue)
|
foreach ($aFoundVariables as $aFoundVariable => $sValue) {
|
||||||
{
|
|
||||||
$aFoundVariablesWithEmptyValue[$aFoundVariable] = '';
|
$aFoundVariablesWithEmptyValue[$aFoundVariable] = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($aToCompleteUrls as $sUrlTemplate)
|
foreach ($aToCompleteUrls as $sUrlTemplate) {
|
||||||
{
|
|
||||||
unset($aToCompleteUrls[$sUrlTemplate]);
|
unset($aToCompleteUrls[$sUrlTemplate]);
|
||||||
$sResolvedUrl = static::ResolveUrl($sUrlTemplate, $aFoundVariables);
|
$sResolvedUrl = static::ResolveUrl($sUrlTemplate, $aFoundVariables);
|
||||||
if ($sResolvedUrl == false)
|
if ($sResolvedUrl == false) {
|
||||||
{
|
|
||||||
$aToCompleteUrls[$sUrlTemplate] = $sUrlTemplate;
|
$aToCompleteUrls[$sUrlTemplate] = $sUrlTemplate;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sUri = static::ResolveUrl($sUrlTemplate, $aFoundVariablesWithEmptyValue);
|
$sUri = static::ResolveUrl($sUrlTemplate, $aFoundVariablesWithEmptyValue);
|
||||||
$aExplodedUri = explode('?', $sUri);
|
$aExplodedUri = explode('?', $sUri);
|
||||||
if (empty($aExplodedUri))
|
if (empty($aExplodedUri)) {
|
||||||
{
|
|
||||||
$aCompleteUrls[$sUri] = $sResolvedUrl;
|
$aCompleteUrls[$sUri] = $sResolvedUrl;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aCompleteUrls[$aExplodedUri[0]] = $sResolvedUrl;
|
$aCompleteUrls[$aExplodedUri[0]] = $sResolvedUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -738,41 +702,31 @@ CSS;
|
|||||||
$aMissingVariables = [];
|
$aMissingVariables = [];
|
||||||
$aFoundVariables = [];
|
$aFoundVariables = [];
|
||||||
|
|
||||||
if (is_file($sStylesheetFile))
|
if (is_file($sStylesheetFile)) {
|
||||||
{
|
|
||||||
$sContent = file_get_contents($sStylesheetFile);
|
$sContent = file_get_contents($sStylesheetFile);
|
||||||
if (preg_match_all("/url\s*\((.*)\)/", $sContent, $aMatches))
|
if (preg_match_all("/url\s*\((.*)\)/", $sContent, $aMatches)) {
|
||||||
{
|
foreach ($aMatches[1] as $path) {
|
||||||
foreach ($aMatches[1] as $path)
|
|
||||||
{
|
|
||||||
$iRemainingClosingParenthesisPos = strpos($path, ')');
|
$iRemainingClosingParenthesisPos = strpos($path, ')');
|
||||||
if ($iRemainingClosingParenthesisPos !== false){
|
if ($iRemainingClosingParenthesisPos !== false) {
|
||||||
$path = substr($path, 0, $iRemainingClosingParenthesisPos);
|
$path = substr($path, 0, $iRemainingClosingParenthesisPos);
|
||||||
}
|
}
|
||||||
if (!array_key_exists($path, $aCompleteUrls)
|
if (!array_key_exists($path, $aCompleteUrls)
|
||||||
&& !array_key_exists($path, $aToCompleteUrls))
|
&& !array_key_exists($path, $aToCompleteUrls)) {
|
||||||
{
|
if (preg_match_all("/\\$([\w\-_]+)/", $path, $aCurrentVars)) {
|
||||||
if (preg_match_all("/\\$([\w\-_]+)/", $path, $aCurrentVars))
|
|
||||||
{
|
|
||||||
/** @var string $aCurrentVars */
|
/** @var string $aCurrentVars */
|
||||||
foreach ($aCurrentVars[1] as $var)
|
foreach ($aCurrentVars[1] as $var) {
|
||||||
{
|
if (!array_key_exists($var, $aMissingVariables)) {
|
||||||
if (!array_key_exists($var, $aMissingVariables))
|
|
||||||
{
|
|
||||||
$aMissingVariables[$var] = $var;
|
$aMissingVariables[$var] = $var;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aToCompleteUrls[$path] = $path;
|
$aToCompleteUrls[$path] = $path;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aCompleteUrls[$path] = trim($path, "\"'");
|
$aCompleteUrls[$path] = trim($path, "\"'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!empty($aMissingVariables))
|
if (!empty($aMissingVariables)) {
|
||||||
{
|
|
||||||
list($aMissingVariables, $aFoundVariables) = static::FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent);
|
list($aMissingVariables, $aFoundVariables) = static::FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent);
|
||||||
list($aToCompleteUrls, $aCompleteUrls) = static::ResolveUrls($aFoundVariables, $aToCompleteUrls, $aCompleteUrls);
|
list($aToCompleteUrls, $aCompleteUrls) = static::ResolveUrls($aFoundVariables, $aToCompleteUrls, $aCompleteUrls);
|
||||||
}
|
}
|
||||||
@@ -782,7 +736,7 @@ CSS;
|
|||||||
'aCompleteUrls' => $aCompleteUrls,
|
'aCompleteUrls' => $aCompleteUrls,
|
||||||
'aToCompleteUrls' => $aToCompleteUrls,
|
'aToCompleteUrls' => $aToCompleteUrls,
|
||||||
'aMissingVariables' => $aMissingVariables,
|
'aMissingVariables' => $aMissingVariables,
|
||||||
'aFoundVariables' => $aFoundVariables
|
'aFoundVariables' => $aFoundVariables,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -796,23 +750,21 @@ CSS;
|
|||||||
*/
|
*/
|
||||||
public static function ResolveUrl($sUrlTemplate, $aFoundVariables)
|
public static function ResolveUrl($sUrlTemplate, $aFoundVariables)
|
||||||
{
|
{
|
||||||
$aPattern= [];
|
$aPattern = [];
|
||||||
$aReplacement= [];
|
$aReplacement = [];
|
||||||
foreach ($aFoundVariables as $aFoundVariable => $aFoundVariableValue)
|
foreach ($aFoundVariables as $aFoundVariable => $aFoundVariableValue) {
|
||||||
{
|
|
||||||
//XX + $key + YY
|
//XX + $key + YY
|
||||||
$aPattern[]="/['\"]\s*\+\s*\\\$" . $aFoundVariable . "[\s\+]+\s*['\"]/";
|
$aPattern[] = "/['\"]\s*\+\s*\\\$".$aFoundVariable."[\s\+]+\s*['\"]/";
|
||||||
$aReplacement[]=$aFoundVariableValue;
|
$aReplacement[] = $aFoundVariableValue;
|
||||||
//$key + YY
|
//$key + YY
|
||||||
$aPattern[]="/\\\$" . $aFoundVariable. "[\s\+]+\s*['\"]/";
|
$aPattern[] = "/\\\$".$aFoundVariable."[\s\+]+\s*['\"]/";
|
||||||
$aReplacement[]=$aFoundVariableValue;
|
$aReplacement[] = $aFoundVariableValue;
|
||||||
//XX + $key
|
//XX + $key
|
||||||
$aPattern[]="/['\"]\s*[\+\s]+\\\$" . $aFoundVariable . "$/";
|
$aPattern[] = "/['\"]\s*[\+\s]+\\\$".$aFoundVariable."$/";
|
||||||
$aReplacement[]=$aFoundVariableValue;
|
$aReplacement[] = $aFoundVariableValue;
|
||||||
}
|
}
|
||||||
$sResolvedUrl=preg_replace($aPattern, $aReplacement, $sUrlTemplate);
|
$sResolvedUrl = preg_replace($aPattern, $aReplacement, $sUrlTemplate);
|
||||||
if (strpos($sResolvedUrl, "+")!==false)
|
if (strpos($sResolvedUrl, "+") !== false) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return trim($sResolvedUrl, "\"'");
|
return trim($sResolvedUrl, "\"'");
|
||||||
@@ -826,17 +778,14 @@ CSS;
|
|||||||
*/
|
*/
|
||||||
private static function HasImageExtension($path)
|
private static function HasImageExtension($path)
|
||||||
{
|
{
|
||||||
foreach (static::IMAGE_EXTENSIONS as $sExt)
|
foreach (static::IMAGE_EXTENSIONS as $sExt) {
|
||||||
{
|
if (endsWith($path, $sExt)) {
|
||||||
if (endsWith($path, $sExt))
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 3.0.0 N°2982
|
* @since 3.0.0 N°2982
|
||||||
* Extract the signature for a generated CSS file.
|
* Extract the signature for a generated CSS file.
|
||||||
@@ -855,16 +804,13 @@ CSS;
|
|||||||
$iCount = 0;
|
$iCount = 0;
|
||||||
$sPreviousLine = '';
|
$sPreviousLine = '';
|
||||||
$hFile = @fopen($sFilepath, "r");
|
$hFile = @fopen($sFilepath, "r");
|
||||||
if ($hFile !== false)
|
if ($hFile !== false) {
|
||||||
{
|
|
||||||
$sLine = '';
|
$sLine = '';
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
$iCount++;
|
$iCount++;
|
||||||
$sPreviousLine = $sLine;
|
$sPreviousLine = $sLine;
|
||||||
$sLine = rtrim(fgets($hFile)); // Remove the trailing \n
|
$sLine = rtrim(fgets($hFile)); // Remove the trailing \n
|
||||||
}
|
} while (($sLine !== false) && ($sLine != '=== SIGNATURE END ===') && ($iCount <= 100));
|
||||||
while (($sLine !== false) && ($sLine != '=== SIGNATURE END ===') && ($iCount <= 100));
|
|
||||||
fclose($hFile);
|
fclose($hFile);
|
||||||
}
|
}
|
||||||
return $sPreviousLine;
|
return $sPreviousLine;
|
||||||
@@ -879,8 +825,7 @@ CSS;
|
|||||||
public static function GetVarSignature($JsonSignature)
|
public static function GetVarSignature($JsonSignature)
|
||||||
{
|
{
|
||||||
$aJsonArray = json_decode($JsonSignature, true);
|
$aJsonArray = json_decode($JsonSignature, true);
|
||||||
if (array_key_exists('variables', $aJsonArray))
|
if (array_key_exists('variables', $aJsonArray)) {
|
||||||
{
|
|
||||||
return $aJsonArray['variables'];
|
return $aJsonArray['variables'];
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -904,23 +849,22 @@ CSS;
|
|||||||
$oFindStylesheetObject->ResetLastStyleSheet();
|
$oFindStylesheetObject->ResetLastStyleSheet();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($aImportsPaths as $sPath)
|
foreach ($aImportsPaths as $sPath) {
|
||||||
{
|
|
||||||
$sAlterableFileURI = $sFileURI;
|
$sAlterableFileURI = $sFileURI;
|
||||||
$sFilePath = $sPath.'/'.$sAlterableFileURI;
|
$sFilePath = $sPath.'/'.$sAlterableFileURI;
|
||||||
$sImportedFile = realpath($sFilePath);
|
$sImportedFile = realpath($sFilePath);
|
||||||
if ($sImportedFile === false){
|
if ($sImportedFile === false) {
|
||||||
// Handle shortcut syntax : @import "typo" ;
|
// Handle shortcut syntax : @import "typo" ;
|
||||||
// file matched: typo.scss
|
// file matched: typo.scss
|
||||||
$sFilePath2 = "$sFilePath.scss";
|
$sFilePath2 = "$sFilePath.scss";
|
||||||
$sImportedFile = realpath($sFilePath2);
|
$sImportedFile = realpath($sFilePath2);
|
||||||
if ($sImportedFile){
|
if ($sImportedFile) {
|
||||||
self::FindStylesheetFile("$sAlterableFileURI.scss", [ $sPath ], $oFindStylesheetObject, $bImports);
|
self::FindStylesheetFile("$sAlterableFileURI.scss", [ $sPath ], $oFindStylesheetObject, $bImports);
|
||||||
$sImportedFile = false;
|
$sImportedFile = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($sImportedFile === false){
|
if ($sImportedFile === false) {
|
||||||
// Handle shortcut syntax : @import "typo" ;
|
// Handle shortcut syntax : @import "typo" ;
|
||||||
// file matched: _typo.scss
|
// file matched: _typo.scss
|
||||||
$sShortCut = substr($sFilePath, strrpos($sFilePath, '/') + 1);
|
$sShortCut = substr($sFilePath, strrpos($sFilePath, '/') + 1);
|
||||||
@@ -930,11 +874,10 @@ CSS;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((file_exists($sImportedFile))
|
if ((file_exists($sImportedFile))
|
||||||
&& (!$oFindStylesheetObject->AlreadyFetched($sImportedFile)))
|
&& (!$oFindStylesheetObject->AlreadyFetched($sImportedFile))) {
|
||||||
{
|
if ($bImports) {
|
||||||
if ($bImports){
|
|
||||||
$oFindStylesheetObject->AddImport($sAlterableFileURI, $sImportedFile);
|
$oFindStylesheetObject->AddImport($sAlterableFileURI, $sImportedFile);
|
||||||
}else{
|
} else {
|
||||||
$oFindStylesheetObject->AddStylesheet($sAlterableFileURI, $sImportedFile);
|
$oFindStylesheetObject->AddStylesheet($sAlterableFileURI, $sImportedFile);
|
||||||
}
|
}
|
||||||
$oFindStylesheetObject->UpdateLastModified($sImportedFile);
|
$oFindStylesheetObject->UpdateLastModified($sImportedFile);
|
||||||
@@ -942,8 +885,8 @@ CSS;
|
|||||||
//Regexp matching on all included scss files : @import 'XXX.scss';
|
//Regexp matching on all included scss files : @import 'XXX.scss';
|
||||||
$sDirUri = dirname($sAlterableFileURI);
|
$sDirUri = dirname($sAlterableFileURI);
|
||||||
preg_match_all('/@import \s*[\"\']([^\"\']*)\s*[\"\']\s*;/', file_get_contents($sImportedFile), $aMatches);
|
preg_match_all('/@import \s*[\"\']([^\"\']*)\s*[\"\']\s*;/', file_get_contents($sImportedFile), $aMatches);
|
||||||
if ( (is_array($aMatches)) && (count($aMatches)!==0) ){
|
if ((is_array($aMatches)) && (count($aMatches) !== 0)) {
|
||||||
foreach ($aMatches[1] as $sImportedFile){
|
foreach ($aMatches[1] as $sImportedFile) {
|
||||||
self::FindStylesheetFile("$sDirUri/$sImportedFile", [ $sPath ], $oFindStylesheetObject, true);
|
self::FindStylesheetFile("$sDirUri/$sImportedFile", [ $sPath ], $oFindStylesheetObject, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -964,8 +907,7 @@ CSS;
|
|||||||
{
|
{
|
||||||
$iPos = strrpos($sSubject, $sSearch);
|
$iPos = strrpos($sSubject, $sSearch);
|
||||||
|
|
||||||
if($iPos !== false)
|
if ($iPos !== false) {
|
||||||
{
|
|
||||||
$sSubject = substr_replace($sSubject, $sReplace, $iPos, strlen($sSearch));
|
$sSubject = substr_replace($sSubject, $sReplace, $iPos, strlen($sSearch));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -994,18 +936,14 @@ CSS;
|
|||||||
public static function CloneThemeParameterAndIncludeVersion($aThemeParameters, $bSetupCompilationTimestamp, $aImportsPaths)
|
public static function CloneThemeParameterAndIncludeVersion($aThemeParameters, $bSetupCompilationTimestamp, $aImportsPaths)
|
||||||
{
|
{
|
||||||
$aThemeParametersVariable = [];
|
$aThemeParametersVariable = [];
|
||||||
if (array_key_exists('variables', $aThemeParameters))
|
if (array_key_exists('variables', $aThemeParameters)) {
|
||||||
{
|
if (is_array($aThemeParameters['variables'])) {
|
||||||
if (is_array($aThemeParameters['variables']))
|
|
||||||
{
|
|
||||||
$aThemeParametersVariable = array_merge([], $aThemeParameters['variables']);
|
$aThemeParametersVariable = array_merge([], $aThemeParameters['variables']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('variable_imports', $aThemeParameters))
|
if (array_key_exists('variable_imports', $aThemeParameters)) {
|
||||||
{
|
if (is_array($aThemeParameters['variable_imports'])) {
|
||||||
if (is_array($aThemeParameters['variable_imports']))
|
|
||||||
{
|
|
||||||
$aThemeParametersVariable = array_merge($aThemeParametersVariable, static::GetVariablesFromFile($aThemeParameters['variable_imports'], $aImportsPaths));
|
$aThemeParametersVariable = array_merge($aThemeParametersVariable, static::GetVariablesFromFile($aThemeParameters['variable_imports'], $aImportsPaths));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1021,11 +959,11 @@ CSS;
|
|||||||
* @return array
|
* @return array
|
||||||
* @since 3.0.0 N°3593
|
* @since 3.0.0 N°3593
|
||||||
*/
|
*/
|
||||||
public static function GetVariablesFromFile($aVariableFiles, $aImportsPaths){
|
public static function GetVariablesFromFile($aVariableFiles, $aImportsPaths)
|
||||||
|
{
|
||||||
$aVariablesResults = [];
|
$aVariablesResults = [];
|
||||||
foreach ($aVariableFiles as $sVariableFile)
|
foreach ($aVariableFiles as $sVariableFile) {
|
||||||
{
|
foreach ($aImportsPaths as $sPath) {
|
||||||
foreach($aImportsPaths as $sPath) {
|
|
||||||
$sFilePath = $sPath.'/'.$sVariableFile;
|
$sFilePath = $sPath.'/'.$sVariableFile;
|
||||||
$sImportedFile = realpath($sFilePath);
|
$sImportedFile = realpath($sFilePath);
|
||||||
if ($sImportedFile !== false) {
|
if ($sImportedFile !== false) {
|
||||||
@@ -1041,9 +979,8 @@ CSS;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
array_map( function($sVariableValue) { return ltrim($sVariableValue); }, $aVariablesResults );
|
array_map(function ($sVariableValue) { return ltrim($sVariableValue); }, $aVariablesResults);
|
||||||
return $aVariablesResults;
|
return $aVariablesResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2024 Combodo SAS
|
* Copyright (C) 2013-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
@@ -29,7 +30,8 @@ class ThemeHandlerService
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function CompileTheme($sThemeId, $bSetup = false, $sSetupCompilationTimestamp = "", $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null){
|
public function CompileTheme($sThemeId, $bSetup = false, $sSetupCompilationTimestamp = "", $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null)
|
||||||
|
{
|
||||||
return ThemeHandler::CompileTheme($sThemeId, $bSetup, $sSetupCompilationTimestamp, $aThemeParameters, $aImportsPaths, $sWorkingPath);
|
return ThemeHandler::CompileTheme($sThemeId, $bSetup, $sSetupCompilationTimestamp, $aThemeParameters, $aImportsPaths, $sWorkingPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// 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
|
// 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
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -22,7 +23,7 @@ use Combodo\iTop\Application\Helper\Session;
|
|||||||
* submitted yet, in order to prevent double submissions. When created a transaction remains valid
|
* submitted yet, in order to prevent double submissions. When created a transaction remains valid
|
||||||
* until the user's session expires. This class is actually a wrapper to the underlying implementation
|
* until the user's session expires. This class is actually a wrapper to the underlying implementation
|
||||||
* which choice is configured via the parameter 'transaction_storage'
|
* which choice is configured via the parameter 'transaction_storage'
|
||||||
*
|
*
|
||||||
* @package iTop
|
* @package iTop
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -37,13 +38,11 @@ class privUITransaction
|
|||||||
public static function GetNewTransactionId()
|
public static function GetNewTransactionId()
|
||||||
{
|
{
|
||||||
$bTransactionsEnabled = MetaModel::GetConfig()->Get('transactions_enabled');
|
$bTransactionsEnabled = MetaModel::GetConfig()->Get('transactions_enabled');
|
||||||
if (!$bTransactionsEnabled)
|
if (!$bTransactionsEnabled) {
|
||||||
{
|
|
||||||
return 'notransactions'; // Any value will do
|
return 'notransactions'; // Any value will do
|
||||||
}
|
}
|
||||||
$sClass = 'privUITransaction'.MetaModel::GetConfig()->Get('transaction_storage');
|
$sClass = 'privUITransaction'.MetaModel::GetConfig()->Get('transaction_storage');
|
||||||
if (!class_exists($sClass, false))
|
if (!class_exists($sClass, false)) {
|
||||||
{
|
|
||||||
IssueLog::Error("Incorrect value '".MetaModel::GetConfig()->Get('transaction_storage')."' for 'transaction_storage', the class '$sClass' does not exists. Using privUITransactionSession instead for storing sessions.");
|
IssueLog::Error("Incorrect value '".MetaModel::GetConfig()->Get('transaction_storage')."' for 'transaction_storage', the class '$sClass' does not exists. Using privUITransactionSession instead for storing sessions.");
|
||||||
$sClass = 'privUITransactionSession';
|
$sClass = 'privUITransactionSession';
|
||||||
}
|
}
|
||||||
@@ -62,16 +61,14 @@ class privUITransaction
|
|||||||
public static function IsTransactionValid($id, $bRemoveTransaction = true)
|
public static function IsTransactionValid($id, $bRemoveTransaction = true)
|
||||||
{
|
{
|
||||||
$bTransactionsEnabled = MetaModel::GetConfig()->Get('transactions_enabled');
|
$bTransactionsEnabled = MetaModel::GetConfig()->Get('transactions_enabled');
|
||||||
if (!$bTransactionsEnabled)
|
if (!$bTransactionsEnabled) {
|
||||||
{
|
|
||||||
return true; // All values are valid
|
return true; // All values are valid
|
||||||
}
|
}
|
||||||
$sClass = 'privUITransaction'.MetaModel::GetConfig()->Get('transaction_storage');
|
$sClass = 'privUITransaction'.MetaModel::GetConfig()->Get('transaction_storage');
|
||||||
if (!class_exists($sClass, false))
|
if (!class_exists($sClass, false)) {
|
||||||
{
|
|
||||||
$sClass = 'privUITransactionSession';
|
$sClass = 'privUITransactionSession';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sClass::IsTransactionValid($id, $bRemoveTransaction);
|
return $sClass::IsTransactionValid($id, $bRemoveTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,16 +80,14 @@ class privUITransaction
|
|||||||
public static function RemoveTransaction($id)
|
public static function RemoveTransaction($id)
|
||||||
{
|
{
|
||||||
$bTransactionsEnabled = MetaModel::GetConfig()->Get('transactions_enabled');
|
$bTransactionsEnabled = MetaModel::GetConfig()->Get('transactions_enabled');
|
||||||
if (!$bTransactionsEnabled)
|
if (!$bTransactionsEnabled) {
|
||||||
{
|
|
||||||
return; // Nothing to do
|
return; // Nothing to do
|
||||||
}
|
}
|
||||||
$sClass = 'privUITransaction'.MetaModel::GetConfig()->Get('transaction_storage');
|
$sClass = 'privUITransaction'.MetaModel::GetConfig()->Get('transaction_storage');
|
||||||
if (!class_exists($sClass, false))
|
if (!class_exists($sClass, false)) {
|
||||||
{
|
|
||||||
$sClass = 'privUITransactionSession';
|
$sClass = 'privUITransactionSession';
|
||||||
}
|
}
|
||||||
|
|
||||||
$sClass::RemoveTransaction($id);
|
$sClass::RemoveTransaction($id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,17 +109,16 @@ class privUITransactionSession
|
|||||||
*/
|
*/
|
||||||
public static function GetNewTransactionId()
|
public static function GetNewTransactionId()
|
||||||
{
|
{
|
||||||
if (!Session::IsSet('transactions'))
|
if (!Session::IsSet('transactions')) {
|
||||||
{
|
|
||||||
Session::Set('transactions', []);
|
Session::Set('transactions', []);
|
||||||
}
|
}
|
||||||
// Strictly speaking, the two lines below should be grouped together
|
// Strictly speaking, the two lines below should be grouped together
|
||||||
// by a critical section
|
// by a critical section
|
||||||
// sem_acquire($rSemIdentified);
|
// sem_acquire($rSemIdentified);
|
||||||
$id = static::GetUserPrefix() . str_replace(array('.', ' '), '', microtime());
|
$id = static::GetUserPrefix().str_replace(['.', ' '], '', microtime());
|
||||||
Session::Set(['transactions', $id], true);
|
Session::Set(['transactions', $id], true);
|
||||||
// sem_release($rSemIdentified);
|
// sem_release($rSemIdentified);
|
||||||
|
|
||||||
return (string)$id;
|
return (string)$id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,20 +129,17 @@ class privUITransactionSession
|
|||||||
* @param int $id Identifier of the transaction, as returned by GetNewTransactionId
|
* @param int $id Identifier of the transaction, as returned by GetNewTransactionId
|
||||||
* @param bool $bRemoveTransaction True if the transaction must be removed
|
* @param bool $bRemoveTransaction True if the transaction must be removed
|
||||||
* @return bool True if the transaction is valid, false otherwise
|
* @return bool True if the transaction is valid, false otherwise
|
||||||
*/
|
*/
|
||||||
public static function IsTransactionValid($id, $bRemoveTransaction = true)
|
public static function IsTransactionValid($id, $bRemoveTransaction = true)
|
||||||
{
|
{
|
||||||
$bResult = false;
|
$bResult = false;
|
||||||
if (Session::IsSet('transactions'))
|
if (Session::IsSet('transactions')) {
|
||||||
{
|
|
||||||
// Strictly speaking, the eight lines below should be grouped together
|
// Strictly speaking, the eight lines below should be grouped together
|
||||||
// inside the same critical section as above
|
// inside the same critical section as above
|
||||||
// sem_acquire($rSemIdentified);
|
// sem_acquire($rSemIdentified);
|
||||||
if (Session::IsSet(['transactions', $id]))
|
if (Session::IsSet(['transactions', $id])) {
|
||||||
{
|
|
||||||
$bResult = true;
|
$bResult = true;
|
||||||
if ($bRemoveTransaction)
|
if ($bRemoveTransaction) {
|
||||||
{
|
|
||||||
Session::Unset(['transactions', $id]);
|
Session::Unset(['transactions', $id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,7 +147,7 @@ class privUITransactionSession
|
|||||||
}
|
}
|
||||||
return $bResult;
|
return $bResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the transaction specified by its id
|
* Removes the transaction specified by its id
|
||||||
* @param int $id The Identifier (as returned by GetNewTranscationId) of the transaction to be removed.
|
* @param int $id The Identifier (as returned by GetNewTranscationId) of the transaction to be removed.
|
||||||
@@ -164,17 +155,15 @@ class privUITransactionSession
|
|||||||
*/
|
*/
|
||||||
public static function RemoveTransaction($id)
|
public static function RemoveTransaction($id)
|
||||||
{
|
{
|
||||||
if (Session::IsSet('transactions'))
|
if (Session::IsSet('transactions')) {
|
||||||
{
|
|
||||||
// Strictly speaking, the three lines below should be grouped together
|
// Strictly speaking, the three lines below should be grouped together
|
||||||
// inside the same critical section as above
|
// inside the same critical section as above
|
||||||
// sem_acquire($rSemIdentified);
|
// sem_acquire($rSemIdentified);
|
||||||
if (Session::IsSet(['transactions', $id]))
|
if (Session::IsSet(['transactions', $id])) {
|
||||||
{
|
|
||||||
Session::Unset(['transactions', $id]);
|
Session::Unset(['transactions', $id]);
|
||||||
}
|
}
|
||||||
// sem_release($rSemIdentified);
|
// sem_release($rSemIdentified);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -197,7 +186,7 @@ class privUITransactionSession
|
|||||||
class privUITransactionFile
|
class privUITransactionFile
|
||||||
{
|
{
|
||||||
/** @var int Value to use when no user logged */
|
/** @var int Value to use when no user logged */
|
||||||
const UNAUTHENTICATED_USER_ID = -666;
|
public const UNAUTHENTICATED_USER_ID = -666;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int current user id, or {@see self::UNAUTHENTICATED_USER_ID} if no user logged
|
* @return int current user id, or {@see self::UNAUTHENTICATED_USER_ID} if no user logged
|
||||||
@@ -228,22 +217,18 @@ class privUITransactionFile
|
|||||||
*/
|
*/
|
||||||
public static function GetNewTransactionId()
|
public static function GetNewTransactionId()
|
||||||
{
|
{
|
||||||
if (!is_dir(APPROOT.'data/transactions'))
|
if (!is_dir(APPROOT.'data/transactions')) {
|
||||||
{
|
if (!is_writable(APPROOT.'data')) {
|
||||||
if (!is_writable(APPROOT.'data'))
|
|
||||||
{
|
|
||||||
throw new Exception('The directory "'.APPROOT.'data" must be writable to the application.');
|
throw new Exception('The directory "'.APPROOT.'data" must be writable to the application.');
|
||||||
}
|
}
|
||||||
// condition avoids race condition N°2345
|
// condition avoids race condition N°2345
|
||||||
// See https://github.com/kalessil/phpinspectionsea/blob/master/docs/probable-bugs.md#mkdir-race-condition
|
// See https://github.com/kalessil/phpinspectionsea/blob/master/docs/probable-bugs.md#mkdir-race-condition
|
||||||
if (!mkdir($concurrentDirectory = APPROOT.'data/transactions') && !is_dir($concurrentDirectory))
|
if (!mkdir($concurrentDirectory = APPROOT.'data/transactions') && !is_dir($concurrentDirectory)) {
|
||||||
{
|
|
||||||
throw new Exception('Failed to create the directory "'.APPROOT.'data/transactions". Ajust the rights on the parent directory or let an administrator create the transactions directory and give the web sever enough rights to write into it.');
|
throw new Exception('Failed to create the directory "'.APPROOT.'data/transactions". Ajust the rights on the parent directory or let an administrator create the transactions directory and give the web sever enough rights to write into it.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_writable(APPROOT.'data/transactions'))
|
if (!is_writable(APPROOT.'data/transactions')) {
|
||||||
{
|
|
||||||
throw new Exception('The directory "'.APPROOT.'data/transactions" must be writable to the application.');
|
throw new Exception('The directory "'.APPROOT.'data/transactions" must be writable to the application.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,8 +262,7 @@ class privUITransactionFile
|
|||||||
// Constraint the transaction file within APPROOT.'data/transactions'
|
// Constraint the transaction file within APPROOT.'data/transactions'
|
||||||
$sTransactionDir = realpath(APPROOT.'data/transactions');
|
$sTransactionDir = realpath(APPROOT.'data/transactions');
|
||||||
$sFilepath = utils::RealPath($sTransactionDir.'/'.$id, $sTransactionDir);
|
$sFilepath = utils::RealPath($sTransactionDir.'/'.$id, $sTransactionDir);
|
||||||
if (($sFilepath === false) || (strlen($sTransactionDir) == strlen($sFilepath)))
|
if (($sFilepath === false) || (strlen($sTransactionDir) == strlen($sFilepath))) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,15 +281,11 @@ class privUITransactionFile
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($bRemoveTransaction)
|
if ($bRemoveTransaction) {
|
||||||
{
|
|
||||||
$bResult = @unlink($sFilepath);
|
$bResult = @unlink($sFilepath);
|
||||||
if (!$bResult)
|
if (!$bResult) {
|
||||||
{
|
|
||||||
self::Error('IsTransactionValid: FAILED to remove transaction '.$id);
|
self::Error('IsTransactionValid: FAILED to remove transaction '.$id);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
self::Info('IsTransactionValid: OK. Removed transaction: '.$id);
|
self::Info('IsTransactionValid: OK. Removed transaction: '.$id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -347,13 +327,11 @@ class privUITransactionFile
|
|||||||
}
|
}
|
||||||
|
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
$iLimit = time() - 24*3600;
|
$iLimit = time() - 24 * 3600;
|
||||||
$sPattern = $sTransactionDir ? "$sTransactionDir/*" : APPROOT.'data/transactions/*';
|
$sPattern = $sTransactionDir ? "$sTransactionDir/*" : APPROOT.'data/transactions/*';
|
||||||
$aTransactions = glob($sPattern);
|
$aTransactions = glob($sPattern);
|
||||||
foreach($aTransactions as $sFileName)
|
foreach ($aTransactions as $sFileName) {
|
||||||
{
|
if (filemtime($sFileName) < $iLimit) {
|
||||||
if (filemtime($sFileName) < $iLimit)
|
|
||||||
{
|
|
||||||
@unlink($sFileName);
|
@unlink($sFileName);
|
||||||
self::Info('CleanupOldTransactions: Deleted transaction: '.$sFileName);
|
self::Info('CleanupOldTransactions: Deleted transaction: '.$sFileName);
|
||||||
}
|
}
|
||||||
@@ -367,10 +345,9 @@ class privUITransactionFile
|
|||||||
protected static function GetPendingTransactions()
|
protected static function GetPendingTransactions()
|
||||||
{
|
{
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
$aResult = array();
|
$aResult = [];
|
||||||
$aTransactions = glob(APPROOT.'data/transactions/'.self::GetUserPrefix().'*');
|
$aTransactions = glob(APPROOT.'data/transactions/'.self::GetUserPrefix().'*');
|
||||||
foreach($aTransactions as $sFileName)
|
foreach ($aTransactions as $sFileName) {
|
||||||
{
|
|
||||||
$aResult[] = date('Y-m-d H:i:s', filemtime($sFileName)).' - '.basename($sFileName);
|
$aResult[] = date('Y-m-d H:i:s', filemtime($sFileName)).' - '.basename($sFileName);
|
||||||
}
|
}
|
||||||
sort($aResult);
|
sort($aResult);
|
||||||
@@ -398,13 +375,14 @@ class privUITransactionFile
|
|||||||
{
|
{
|
||||||
self::Write('Warning | '.$sText);
|
self::Write('Warning | '.$sText);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function Error($sText)
|
protected static function Error($sText)
|
||||||
{
|
{
|
||||||
self::Write('Error | '.$sText);
|
self::Write('Error | '.$sText);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function IsLogEnabled() {
|
protected static function IsLogEnabled()
|
||||||
|
{
|
||||||
$oConfig = MetaModel::GetConfig();
|
$oConfig = MetaModel::GetConfig();
|
||||||
if (is_null($oConfig)) {
|
if (is_null($oConfig)) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -34,24 +34,32 @@ class TwigExtension
|
|||||||
{
|
{
|
||||||
// Filter to translate a string via the Dict::S function
|
// Filter to translate a string via the Dict::S function
|
||||||
// Usage in twig: {{ 'String:ToTranslate'|dict_s }}
|
// Usage in twig: {{ 'String:ToTranslate'|dict_s }}
|
||||||
$oTwigEnv->addFilter(new TwigFilter('dict_s',
|
$oTwigEnv->addFilter(
|
||||||
|
new TwigFilter(
|
||||||
|
'dict_s',
|
||||||
function ($sStringCode, $sDefault = null, $bUserLanguageOnly = false) {
|
function ($sStringCode, $sDefault = null, $bUserLanguageOnly = false) {
|
||||||
return Dict::S($sStringCode, $sDefault, $bUserLanguageOnly);
|
return Dict::S($sStringCode, $sDefault, $bUserLanguageOnly);
|
||||||
})
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Filter to format a string via the Dict::Format function
|
// Filter to format a string via the Dict::Format function
|
||||||
// Usage in twig: {{ 'String:ToTranslate'|dict_format() }}
|
// Usage in twig: {{ 'String:ToTranslate'|dict_format() }}
|
||||||
$oTwigEnv->addFilter(new TwigFilter('dict_format',
|
$oTwigEnv->addFilter(
|
||||||
|
new TwigFilter(
|
||||||
|
'dict_format',
|
||||||
function ($sStringCode, $sParam01 = null, $sParam02 = null, $sParam03 = null, $sParam04 = null) {
|
function ($sStringCode, $sParam01 = null, $sParam02 = null, $sParam03 = null, $sParam04 = null) {
|
||||||
return Dict::Format($sStringCode, $sParam01, $sParam02, $sParam03, $sParam04);
|
return Dict::Format($sStringCode, $sParam01, $sParam02, $sParam03, $sParam04);
|
||||||
})
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Filter to format output
|
// Filter to format output
|
||||||
// example a DateTime is converted to user format
|
// example a DateTime is converted to user format
|
||||||
// Usage in twig: {{ 'String:ToFormat'|output_format }}
|
// Usage in twig: {{ 'String:ToFormat'|output_format }}
|
||||||
$oTwigEnv->addFilter(new TwigFilter('date_format',
|
$oTwigEnv->addFilter(
|
||||||
|
new TwigFilter(
|
||||||
|
'date_format',
|
||||||
function ($sDate) {
|
function ($sDate) {
|
||||||
try {
|
try {
|
||||||
if (preg_match('@^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d$@', trim($sDate))) {
|
if (preg_match('@^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d$@', trim($sDate))) {
|
||||||
@@ -60,22 +68,23 @@ class TwigExtension
|
|||||||
if (preg_match('@^\d\d\d\d-\d\d-\d\d$@', trim($sDate))) {
|
if (preg_match('@^\d\d\d\d-\d\d-\d\d$@', trim($sDate))) {
|
||||||
return AttributeDate::GetFormat()->Format($sDate);
|
return AttributeDate::GetFormat()->Format($sDate);
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
return $sDate;
|
return $sDate;
|
||||||
})
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Filter to format output
|
// Filter to format output
|
||||||
// example a DateTime is converted to user format
|
// example a DateTime is converted to user format
|
||||||
// Usage in twig: {{ 'String:ToFormat'|output_format }}
|
// Usage in twig: {{ 'String:ToFormat'|output_format }}
|
||||||
$oTwigEnv->addFilter(new TwigFilter('size_format',
|
$oTwigEnv->addFilter(
|
||||||
|
new TwigFilter(
|
||||||
|
'size_format',
|
||||||
function ($sSize) {
|
function ($sSize) {
|
||||||
return utils::BytesToFriendlyFormat($sSize);
|
return utils::BytesToFriendlyFormat($sSize);
|
||||||
})
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Filter to enable base64 encode/decode
|
// Filter to enable base64 encode/decode
|
||||||
@@ -85,7 +94,8 @@ class TwigExtension
|
|||||||
|
|
||||||
// Filter to enable json decode (encode already exists)
|
// Filter to enable json decode (encode already exists)
|
||||||
// Usage in twig: {{ aSomeArray|json_decode }}
|
// Usage in twig: {{ aSomeArray|json_decode }}
|
||||||
$oTwigEnv->addFilter(new TwigFilter('json_decode', function ($sJsonString, $bAssoc = false) {
|
$oTwigEnv->addFilter(
|
||||||
|
new TwigFilter('json_decode', function ($sJsonString, $bAssoc = false) {
|
||||||
return json_decode($sJsonString, $bAssoc);
|
return json_decode($sJsonString, $bAssoc);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -54,8 +55,8 @@ require_once(APPROOT.'/application/displayblock.class.inc.php');
|
|||||||
*/
|
*/
|
||||||
class UIExtKeyWidget
|
class UIExtKeyWidget
|
||||||
{
|
{
|
||||||
const ENUM_OUTPUT_FORMAT_CSV = 'csv';
|
public const ENUM_OUTPUT_FORMAT_CSV = 'csv';
|
||||||
const ENUM_OUTPUT_FORMAT_JSON = 'json';
|
public const ENUM_OUTPUT_FORMAT_JSON = 'json';
|
||||||
|
|
||||||
protected $iId;
|
protected $iId;
|
||||||
protected $sTargetClass;
|
protected $sTargetClass;
|
||||||
@@ -87,10 +88,20 @@ class UIExtKeyWidget
|
|||||||
* @since 2.7.7 3.0.1 3.1.0 N°3129 Add default value for $aArgs for PHP 8.0 compat
|
* @since 2.7.7 3.0.1 3.1.0 N°3129 Add default value for $aArgs for PHP 8.0 compat
|
||||||
*/
|
*/
|
||||||
public static function DisplayFromAttCode(
|
public static function DisplayFromAttCode(
|
||||||
$oPage, $sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName = '', $sFormPrefix = '',
|
$oPage,
|
||||||
$aArgs = [], $bSearchMode = false, &$sInputType = ''
|
$sAttCode,
|
||||||
)
|
$sClass,
|
||||||
{
|
$sTitle,
|
||||||
|
$oAllowedValues,
|
||||||
|
$value,
|
||||||
|
$iInputId,
|
||||||
|
$bMandatory,
|
||||||
|
$sFieldName = '',
|
||||||
|
$sFormPrefix = '',
|
||||||
|
$aArgs = [],
|
||||||
|
$bSearchMode = false,
|
||||||
|
&$sInputType = ''
|
||||||
|
) {
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
$sTargetClass = $oAttDef->GetTargetClass();
|
$sTargetClass = $oAttDef->GetTargetClass();
|
||||||
$iMaxComboLength = $oAttDef->GetMaximumComboLength();
|
$iMaxComboLength = $oAttDef->GetMaximumComboLength();
|
||||||
@@ -102,8 +113,7 @@ class UIExtKeyWidget
|
|||||||
}
|
}
|
||||||
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode, $bSearchMode);
|
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode, $bSearchMode);
|
||||||
if (!$bSearchMode) {
|
if (!$bSearchMode) {
|
||||||
switch ($sDisplayStyle)
|
switch ($sDisplayStyle) {
|
||||||
{
|
|
||||||
case 'radio':
|
case 'radio':
|
||||||
case 'radio_horizontal':
|
case 'radio_horizontal':
|
||||||
case 'radio_vertical':
|
case 'radio_vertical':
|
||||||
@@ -114,12 +124,38 @@ class UIExtKeyWidget
|
|||||||
case 'select':
|
case 'select':
|
||||||
case 'list':
|
case 'list':
|
||||||
default:
|
default:
|
||||||
return $oWidget->DisplaySelect($oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value,
|
return $oWidget->DisplaySelect(
|
||||||
$bMandatory, $sFieldName, $sFormPrefix, $aArgs, $sInputType);
|
$oPage,
|
||||||
|
$iMaxComboLength,
|
||||||
|
$bAllowTargetCreation,
|
||||||
|
$sTitle,
|
||||||
|
$oAllowedValues,
|
||||||
|
$value,
|
||||||
|
$bMandatory,
|
||||||
|
$sFieldName,
|
||||||
|
$sFormPrefix,
|
||||||
|
$aArgs,
|
||||||
|
$sInputType
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return $oWidget->Display($oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value, $iInputId,
|
return $oWidget->Display(
|
||||||
$bMandatory, $sFieldName, $sFormPrefix, $aArgs, null, $sDisplayStyle, true, $sInputType);
|
$oPage,
|
||||||
|
$iMaxComboLength,
|
||||||
|
$bAllowTargetCreation,
|
||||||
|
$sTitle,
|
||||||
|
$oAllowedValues,
|
||||||
|
$value,
|
||||||
|
$iInputId,
|
||||||
|
$bMandatory,
|
||||||
|
$sFieldName,
|
||||||
|
$sFormPrefix,
|
||||||
|
$aArgs,
|
||||||
|
null,
|
||||||
|
$sDisplayStyle,
|
||||||
|
true,
|
||||||
|
$sInputType
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +194,7 @@ class UIExtKeyWidget
|
|||||||
* @since 3.0.0 N°2508 - Include Obsolescence icon within list and autocomplete
|
* @since 3.0.0 N°2508 - Include Obsolescence icon within list and autocomplete
|
||||||
* @since 3.0.0 N°3750 new $sInputType parameter
|
* @since 3.0.0 N°3750 new $sInputType parameter
|
||||||
*/
|
*/
|
||||||
public function DisplaySelect(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array(), &$sInputType = '')
|
public function DisplaySelect(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = [], &$sInputType = '')
|
||||||
{
|
{
|
||||||
$sTitle = addslashes($sTitle);
|
$sTitle = addslashes($sTitle);
|
||||||
$oPage->LinkScriptFromAppRoot('js/extkeywidget.js');
|
$oPage->LinkScriptFromAppRoot('js/extkeywidget.js');
|
||||||
@@ -194,7 +230,7 @@ class UIExtKeyWidget
|
|||||||
$bIsAutocomplete = $oAllowedValues->CountExceeds($iMaxComboLength);
|
$bIsAutocomplete = $oAllowedValues->CountExceeds($iMaxComboLength);
|
||||||
$sWrapperCssClass = $bIsAutocomplete ? 'ibo-input-select-autocomplete-wrapper' : 'ibo-input-select-wrapper';
|
$sWrapperCssClass = $bIsAutocomplete ? 'ibo-input-select-autocomplete-wrapper' : 'ibo-input-select-wrapper';
|
||||||
$sHTMLValue = "<div class=\"field_input_zone field_input_extkey ibo-input-wrapper ibo-input-select-wrapper--with-buttons $sWrapperCssClass\" data-attcode=\"".$this->sAttCode."\" data-validation=\"untouched\" data-accessibility-selectize-label=\"$sTitle\">";
|
$sHTMLValue = "<div class=\"field_input_zone field_input_extkey ibo-input-wrapper ibo-input-select-wrapper--with-buttons $sWrapperCssClass\" data-attcode=\"".$this->sAttCode."\" data-validation=\"untouched\" data-accessibility-selectize-label=\"$sTitle\">";
|
||||||
|
|
||||||
// We just need to compare the number of entries with MaxComboLength, so no need to get the real count.
|
// We just need to compare the number of entries with MaxComboLength, so no need to get the real count.
|
||||||
if (!$bIsAutocomplete) {
|
if (!$bIsAutocomplete) {
|
||||||
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
|
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
|
||||||
@@ -281,21 +317,17 @@ EOF
|
|||||||
$oPage->add_ready_script("$('#$this->iId').one('validate', function() { $(this).trigger('change'); } );");
|
$oPage->add_ready_script("$('#$this->iId').one('validate', function() { $(this).trigger('change'); } );");
|
||||||
}
|
}
|
||||||
$sHTMLValue .= "<div class=\"ibo-input-select--action-buttons\">";
|
$sHTMLValue .= "<div class=\"ibo-input-select--action-buttons\">";
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Too many choices, use an autocomplete
|
// Too many choices, use an autocomplete
|
||||||
// Check that the given value is allowed
|
// Check that the given value is allowed
|
||||||
$oSearch = $oAllowedValues->GetFilter();
|
$oSearch = $oAllowedValues->GetFilter();
|
||||||
$oSearch->AddCondition('id', $value);
|
$oSearch->AddCondition('id', $value);
|
||||||
$oSet = new DBObjectSet($oSearch);
|
$oSet = new DBObjectSet($oSearch);
|
||||||
if ($oSet->Count() == 0)
|
if ($oSet->Count() == 0) {
|
||||||
{
|
|
||||||
$value = null;
|
$value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_null($value) || ($value == 0)) // Null values are displayed as ''
|
if (is_null($value) || ($value == 0)) { // Null values are displayed as ''
|
||||||
{
|
|
||||||
$sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : '';
|
$sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : '';
|
||||||
} else {
|
} else {
|
||||||
$sDisplayValue = $this->GetObjectName($value);
|
$sDisplayValue = $this->GetObjectName($value);
|
||||||
@@ -376,36 +408,30 @@ JS
|
|||||||
|
|
||||||
$sHTMLValue = "<div class=\"field_input_zone field_input_extkey\">";
|
$sHTMLValue = "<div class=\"field_input_zone field_input_extkey\">";
|
||||||
|
|
||||||
if (is_null($oAllowedValues))
|
if (is_null($oAllowedValues)) {
|
||||||
{
|
|
||||||
throw new Exception('Implementation: null value for allowed values definition');
|
throw new Exception('Implementation: null value for allowed values definition');
|
||||||
}
|
}
|
||||||
$oAllowedValues->SetShowObsoleteData(utils::ShowObsoleteData());
|
$oAllowedValues->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||||
|
|
||||||
// We just need to compare the number of entries with MaxComboLength, so no need to get the real count.
|
// We just need to compare the number of entries with MaxComboLength, so no need to get the real count.
|
||||||
if (!$oAllowedValues->CountExceeds($iMaxComboLength))
|
if (!$oAllowedValues->CountExceeds($iMaxComboLength)) {
|
||||||
{
|
|
||||||
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
|
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
|
||||||
$sValidationField = null;
|
$sValidationField = null;
|
||||||
|
|
||||||
$bVertical = ($sDisplayStyle != 'radio_horizontal');
|
$bVertical = ($sDisplayStyle != 'radio_horizontal');
|
||||||
$bExtensions = false;
|
$bExtensions = false;
|
||||||
$oAllowedValues->Rewind();
|
$oAllowedValues->Rewind();
|
||||||
$aAllowedValues = array();
|
$aAllowedValues = [];
|
||||||
while($oObj = $oAllowedValues->Fetch())
|
while ($oObj = $oAllowedValues->Fetch()) {
|
||||||
{
|
|
||||||
$aAllowedValues[$oObj->GetKey()] = $oObj->GetName();
|
$aAllowedValues[$oObj->GetKey()] = $oObj->GetName();
|
||||||
}
|
}
|
||||||
$sHTMLValue .= $oPage->GetRadioButtons($aAllowedValues, $value, $this->iId, "{$sAttrFieldPrefix}{$sFieldName}", false /* $bMandatory will be placed manually */, $bVertical, $sValidationField);
|
$sHTMLValue .= $oPage->GetRadioButtons($aAllowedValues, $value, $this->iId, "{$sAttrFieldPrefix}{$sFieldName}", false /* $bMandatory will be placed manually */, $bVertical, $sValidationField);
|
||||||
$aEventsList[] ='change';
|
$aEventsList[] = 'change';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sHTMLValue .= "unable to display. Too much values";
|
$sHTMLValue .= "unable to display. Too much values";
|
||||||
}
|
}
|
||||||
$sHTMLValue .= '<div class="ibo-input-select--action-buttons">';
|
$sHTMLValue .= '<div class="ibo-input-select--action-buttons">';
|
||||||
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false)
|
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false) {
|
||||||
{
|
|
||||||
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"><i class=\"fas fa-sitemap\"></i></div></span>";
|
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"><i class=\"fas fa-sitemap\"></i></div></span>";
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<JS
|
<<<JS
|
||||||
@@ -416,8 +442,7 @@ JS
|
|||||||
JS
|
JS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ($bCreate && $bExtensions)
|
if ($bCreate && $bExtensions) {
|
||||||
{
|
|
||||||
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
|
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
|
||||||
|
|
||||||
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\"><i class=\"fas fa-plus\"></i></div></span>";
|
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\"><i class=\"fas fa-plus\"></i></div></span>";
|
||||||
@@ -471,7 +496,7 @@ JS
|
|||||||
*
|
*
|
||||||
* @since 3.0.0 N°3750 new $sInputType parameter
|
* @since 3.0.0 N°3750 new $sInputType parameter
|
||||||
*/
|
*/
|
||||||
public function Display(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array(), $bSearchMode = null, $sDisplayStyle = 'select', $bSearchMultiple = true, &$sInputType = '')
|
public function Display(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = [], $bSearchMode = null, $sDisplayStyle = 'select', $bSearchMultiple = true, &$sInputType = '')
|
||||||
{
|
{
|
||||||
if (!is_null($bSearchMode)) {
|
if (!is_null($bSearchMode)) {
|
||||||
$this->bSearchMode = $bSearchMode;
|
$this->bSearchMode = $bSearchMode;
|
||||||
@@ -521,7 +546,7 @@ JS
|
|||||||
$bVertical = ($sDisplayStyle != 'radio_horizontal');
|
$bVertical = ($sDisplayStyle != 'radio_horizontal');
|
||||||
$bExtensions = false;
|
$bExtensions = false;
|
||||||
$oAllowedValues->Rewind();
|
$oAllowedValues->Rewind();
|
||||||
$aAllowedValues = array();
|
$aAllowedValues = [];
|
||||||
while ($oObj = $oAllowedValues->Fetch()) {
|
while ($oObj = $oAllowedValues->Fetch()) {
|
||||||
$aAllowedValues[$oObj->GetKey()] = $oObj->GetName();
|
$aAllowedValues[$oObj->GetKey()] = $oObj->GetName();
|
||||||
}
|
}
|
||||||
@@ -568,22 +593,22 @@ EOF
|
|||||||
}
|
}
|
||||||
$sHTMLValue .= "<option value=\"$key\" $sSelected>$display_value</option>\n";
|
$sHTMLValue .= "<option value=\"$key\" $sSelected>$display_value</option>\n";
|
||||||
}
|
}
|
||||||
$sHTMLValue .= "</select>\n";
|
$sHTMLValue .= "</select>\n";
|
||||||
$sHTMLValue .= "</div>\n";
|
$sHTMLValue .= "</div>\n";
|
||||||
|
|
||||||
$sInputType = CmdbAbstractObject::ENUM_INPUT_TYPE_DROPDOWN_RAW;
|
$sInputType = CmdbAbstractObject::ENUM_INPUT_TYPE_DROPDOWN_RAW;
|
||||||
if (($this->bSearchMode) && $bSearchMultiple) {
|
if (($this->bSearchMode) && $bSearchMultiple) {
|
||||||
$sInputType = CmdbAbstractObject::ENUM_INPUT_TYPE_DROPDOWN_MULTIPLE_CHOICES;
|
$sInputType = CmdbAbstractObject::ENUM_INPUT_TYPE_DROPDOWN_MULTIPLE_CHOICES;
|
||||||
$aOptions = array(
|
$aOptions = [
|
||||||
'header' => true,
|
'header' => true,
|
||||||
'checkAllText' => Dict::S('UI:SearchValue:CheckAll'),
|
'checkAllText' => Dict::S('UI:SearchValue:CheckAll'),
|
||||||
'uncheckAllText' => Dict::S('UI:SearchValue:UncheckAll'),
|
'uncheckAllText' => Dict::S('UI:SearchValue:UncheckAll'),
|
||||||
'noneSelectedText' => Dict::S('UI:SearchValue:Any'),
|
'noneSelectedText' => Dict::S('UI:SearchValue:Any'),
|
||||||
'selectedText' => Dict::S('UI:SearchValue:NbSelected'),
|
'selectedText' => Dict::S('UI:SearchValue:NbSelected'),
|
||||||
'selectedList' => 1,
|
'selectedList' => 1,
|
||||||
);
|
];
|
||||||
$sJSOptions = json_encode($aOptions);
|
$sJSOptions = json_encode($aOptions);
|
||||||
$oPage->add_ready_script("$('.multiselect').multiselect($sJSOptions);");
|
$oPage->add_ready_script("$('.multiselect').multiselect($sJSOptions);");
|
||||||
}
|
}
|
||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
@@ -606,8 +631,7 @@ EOF
|
|||||||
$value = null;
|
$value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_null($value) || ($value == 0)) // Null values are displayed as ''
|
if (is_null($value) || ($value == 0)) { // Null values are displayed as ''
|
||||||
{
|
|
||||||
$sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : '';
|
$sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : '';
|
||||||
} else {
|
} else {
|
||||||
$sDisplayValue = $this->GetObjectName($value);
|
$sDisplayValue = $this->GetObjectName($value);
|
||||||
@@ -673,20 +697,22 @@ JS
|
|||||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oCurrObject), $this->sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef(get_class($oCurrObject), $this->sAttCode);
|
||||||
/** @var \DBObject $oCurrObject */
|
/** @var \DBObject $oCurrObject */
|
||||||
$aArgs = $oCurrObject->ToArgsForQuery();
|
$aArgs = $oCurrObject->ToArgsForQuery();
|
||||||
$aParams = array('query_params' => $aArgs);
|
$aParams = ['query_params' => $aArgs];
|
||||||
$oSet = $oAttDef->GetAllowedValuesAsObjectSet($aArgs);
|
$oSet = $oAttDef->GetAllowedValuesAsObjectSet($aArgs);
|
||||||
$oFilter = $oSet->GetFilter();
|
$oFilter = $oSet->GetFilter();
|
||||||
} else if (!empty($this->sFilter)) {
|
} elseif (!empty($this->sFilter)) {
|
||||||
$aParams = array();
|
$aParams = [];
|
||||||
$oFilter = DBObjectSearch::FromOQL($this->sFilter);
|
$oFilter = DBObjectSearch::FromOQL($this->sFilter);
|
||||||
} else {
|
} else {
|
||||||
$aParams = array();
|
$aParams = [];
|
||||||
$oFilter = new DBObjectSearch($this->sTargetClass);
|
$oFilter = new DBObjectSearch($this->sTargetClass);
|
||||||
}
|
}
|
||||||
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||||
$oBlock = new DisplayBlock($oFilter, 'search', false, $aParams);
|
$oBlock = new DisplayBlock($oFilter, 'search', false, $aParams);
|
||||||
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, 'dtc_'.$this->iId,
|
$oPage->AddUiBlock($oBlock->GetDisplay(
|
||||||
array(
|
$oPage,
|
||||||
|
'dtc_'.$this->iId,
|
||||||
|
[
|
||||||
'menu' => false,
|
'menu' => false,
|
||||||
'currentId' => $this->iId,
|
'currentId' => $this->iId,
|
||||||
'table_id' => "dr_{$this->iId}",
|
'table_id' => "dr_{$this->iId}",
|
||||||
@@ -694,12 +720,13 @@ JS
|
|||||||
'selection_mode' => true,
|
'selection_mode' => true,
|
||||||
'selection_type' => 'single',
|
'selection_type' => 'single',
|
||||||
'cssCount' => '#count_'.$this->iId.'_results',
|
'cssCount' => '#count_'.$this->iId.'_results',
|
||||||
)
|
]
|
||||||
));
|
));
|
||||||
$sCancel = Dict::S('UI:Button:Cancel');
|
$sCancel = Dict::S('UI:Button:Cancel');
|
||||||
$sOK = Dict::S('UI:Button:Ok');
|
$sOK = Dict::S('UI:Button:Ok');
|
||||||
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||||
$oPage->add(<<<HTML
|
$oPage->add(
|
||||||
|
<<<HTML
|
||||||
<form id="fr_{$this->iId}" OnSubmit="return oACWidget_{$this->iId}.DoOk();">
|
<form id="fr_{$this->iId}" OnSubmit="return oACWidget_{$this->iId}.DoOk();">
|
||||||
<div id="dr_{$this->iId}">
|
<div id="dr_{$this->iId}">
|
||||||
<div><p>{$sEmptyList}</p></div>
|
<div><p>{$sEmptyList}</p></div>
|
||||||
@@ -711,7 +738,8 @@ HTML
|
|||||||
);
|
);
|
||||||
|
|
||||||
$sDialogTitleSanitized = addslashes(utils::HtmlToText($sTitle));
|
$sDialogTitleSanitized = addslashes(utils::HtmlToText($sTitle));
|
||||||
$oPage->add_ready_script(<<<JS
|
$oPage->add_ready_script(
|
||||||
|
<<<JS
|
||||||
$('#ac_dlg_{$this->iId}').dialog({
|
$('#ac_dlg_{$this->iId}').dialog({
|
||||||
width: $(window).width()*0.8,
|
width: $(window).width()*0.8,
|
||||||
height: $(window).height()*0.8,
|
height: $(window).height()*0.8,
|
||||||
@@ -751,14 +779,12 @@ JS
|
|||||||
*/
|
*/
|
||||||
public function SearchObjectsToSelect(WebPage $oP, $sFilter, $sRemoteClass = '', $oObj = null)
|
public function SearchObjectsToSelect(WebPage $oP, $sFilter, $sRemoteClass = '', $oObj = null)
|
||||||
{
|
{
|
||||||
if (is_null($sFilter))
|
if (is_null($sFilter)) {
|
||||||
{
|
|
||||||
throw new Exception('Implementation: null value for allowed values definition');
|
throw new Exception('Implementation: null value for allowed values definition');
|
||||||
}
|
}
|
||||||
|
|
||||||
$oFilter = DBObjectSearch::FromOQL($sFilter);
|
$oFilter = DBObjectSearch::FromOQL($sFilter);
|
||||||
if (strlen($sRemoteClass) > 0)
|
if (strlen($sRemoteClass) > 0) {
|
||||||
{
|
|
||||||
$oFilter->ChangeClass($sRemoteClass);
|
$oFilter->ChangeClass($sRemoteClass);
|
||||||
}
|
}
|
||||||
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||||
@@ -766,26 +792,26 @@ JS
|
|||||||
// Current extkey value, so we can display event if it is not available anymore (eg. archived).
|
// Current extkey value, so we can display event if it is not available anymore (eg. archived).
|
||||||
$iCurrentExtKeyId = (is_null($oObj)) ? 0 : $oObj->Get($this->sAttCode);
|
$iCurrentExtKeyId = (is_null($oObj)) ? 0 : $oObj->Get($this->sAttCode);
|
||||||
|
|
||||||
$oBlock = new DisplayBlock($oFilter, 'list_search', false, array('query_params' => array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId)));
|
$oBlock = new DisplayBlock($oFilter, 'list_search', false, ['query_params' => ['this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId]]);
|
||||||
$oBlock->Display($oP, $this->iId.'_results', array('this' => $oObj, 'cssCount'=> '#count_'.$this->iId.'_results', 'menu' => false, 'selection_mode' => true, 'selection_type' => 'single', 'table_id' => 'select_'.$this->sAttCode)); // Don't display the 'Actions' menu on the results
|
$oBlock->Display($oP, $this->iId.'_results', ['this' => $oObj, 'cssCount' => '#count_'.$this->iId.'_results', 'menu' => false, 'selection_mode' => true, 'selection_type' => 'single', 'table_id' => 'select_'.$this->sAttCode]); // Don't display the 'Actions' menu on the results
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search for objects to be selected
|
* Search for objects to be selected
|
||||||
*
|
*
|
||||||
* @param WebPage $oP The page used for the output (usually an AjaxWebPage)
|
* @param WebPage $oP The page used for the output (usually an AjaxWebPage)
|
||||||
* @param string $sFilter The OQL expression used to define/limit limit the scope of possible values
|
* @param string $sFilter The OQL expression used to define/limit limit the scope of possible values
|
||||||
* @param DBObject $oObj The current object for the OQL context
|
* @param DBObject $oObj The current object for the OQL context
|
||||||
* @param string $sContains The text of the autocomplete to filter the results
|
* @param string $sContains The text of the autocomplete to filter the results
|
||||||
* @param string $sOutputFormat
|
* @param string $sOutputFormat
|
||||||
* @param null $sOperation for the values @see ValueSetObjects->LoadValues() not used since 3.0.0
|
* @param null $sOperation for the values @see ValueSetObjects->LoadValues() not used since 3.0.0
|
||||||
*
|
*
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
* @throws OQLException
|
* @throws OQLException
|
||||||
*
|
*
|
||||||
* @since 2.7.7 3.0.1 3.1.0 N°3129 Remove default value for $oObj for PHP 8.0 compatibility
|
* @since 2.7.7 3.0.1 3.1.0 N°3129 Remove default value for $oObj for PHP 8.0 compatibility
|
||||||
*/
|
*/
|
||||||
public function AutoComplete(WebPage $oP, $sFilter, $oObj, $sContains, $sOutputFormat = self::ENUM_OUTPUT_FORMAT_CSV, $sOperation = null )
|
public function AutoComplete(WebPage $oP, $sFilter, $oObj, $sContains, $sOutputFormat = self::ENUM_OUTPUT_FORMAT_CSV, $sOperation = null)
|
||||||
{
|
{
|
||||||
if (is_null($sFilter)) {
|
if (is_null($sFilter)) {
|
||||||
throw new Exception('Implementation: null value for allowed values definition');
|
throw new Exception('Implementation: null value for allowed values definition');
|
||||||
@@ -799,38 +825,32 @@ JS
|
|||||||
$oValuesSet->SetSort(false);
|
$oValuesSet->SetSort(false);
|
||||||
$oValuesSet->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
$oValuesSet->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||||
$oValuesSet->SetLimit($iMax);
|
$oValuesSet->SetLimit($iMax);
|
||||||
$aValuesStartWith = $oValuesSet->GetValuesForAutocomplete(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'start_with');
|
$aValuesStartWith = $oValuesSet->GetValuesForAutocomplete(['this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId], $sContains, 'start_with');
|
||||||
asort($aValuesStartWith);
|
asort($aValuesStartWith);
|
||||||
$aValues = $aValuesStartWith;
|
$aValues = $aValuesStartWith;
|
||||||
if (sizeof($aValues) < $iMax) {
|
if (sizeof($aValues) < $iMax) {
|
||||||
$aValuesContains = $oValuesSet->GetValuesForAutocomplete(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'contains');
|
$aValuesContains = $oValuesSet->GetValuesForAutocomplete(['this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId], $sContains, 'contains');
|
||||||
asort($aValuesContains);
|
asort($aValuesContains);
|
||||||
$iSize = sizeof($aValues);
|
$iSize = sizeof($aValues);
|
||||||
foreach ($aValuesContains as $sKey => $sFriendlyName)
|
foreach ($aValuesContains as $sKey => $sFriendlyName) {
|
||||||
{
|
if (!isset($aValues[$sKey])) {
|
||||||
if (!isset($aValues[$sKey]))
|
|
||||||
{
|
|
||||||
$aValues[$sKey] = $sFriendlyName;
|
$aValues[$sKey] = $sFriendlyName;
|
||||||
if (++$iSize >= $iMax)
|
if (++$iSize >= $iMax) {
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} elseif (!in_array($sContains, $aValues)) {
|
||||||
elseif (!in_array($sContains, $aValues))
|
$aValuesEquals = $oValuesSet->GetValuesForAutocomplete(['this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId], $sContains, 'equals');
|
||||||
{
|
|
||||||
$aValuesEquals = $oValuesSet->GetValuesForAutocomplete(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'equals');
|
|
||||||
// Note: Here we cannot use array_merge as it would reindex the numeric keys starting from 0 when keys are actually the objects ID.
|
// Note: Here we cannot use array_merge as it would reindex the numeric keys starting from 0 when keys are actually the objects ID.
|
||||||
// As a workaround we use array_replace as it does preserve numeric keys. It's ok if some values from $aValuesEquals are replaced with values from $aValues as they contain the same data.
|
// As a workaround we use array_replace as it does preserve numeric keys. It's ok if some values from $aValuesEquals are replaced with values from $aValues as they contain the same data.
|
||||||
$aValues = array_replace($aValuesEquals, $aValues);
|
$aValues = array_replace($aValuesEquals, $aValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch($sOutputFormat)
|
switch ($sOutputFormat) {
|
||||||
{
|
|
||||||
case static::ENUM_OUTPUT_FORMAT_JSON:
|
case static::ENUM_OUTPUT_FORMAT_JSON:
|
||||||
|
|
||||||
$aJsonMap = array();
|
$aJsonMap = [];
|
||||||
foreach ($aValues as $sKey => $aValue) {
|
foreach ($aValues as $sKey => $aValue) {
|
||||||
$aElt = ['value' => $sKey, 'label' => utils::EscapeHtml($aValue['label']), 'obsolescence_flag' => $aValue['obsolescence_flag']];
|
$aElt = ['value' => $sKey, 'label' => utils::EscapeHtml($aValue['label']), 'obsolescence_flag' => $aValue['obsolescence_flag']];
|
||||||
if ($aValue['additional_field'] != '') {
|
if ($aValue['additional_field'] != '') {
|
||||||
@@ -851,8 +871,7 @@ JS
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case static::ENUM_OUTPUT_FORMAT_CSV:
|
case static::ENUM_OUTPUT_FORMAT_CSV:
|
||||||
foreach($aValues as $sKey => $aValue)
|
foreach ($aValues as $sKey => $aValue) {
|
||||||
{
|
|
||||||
$oP->add(trim($aValue['label'])."\t".$sKey."\n");
|
$oP->add(trim($aValue['label'])."\t".$sKey."\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -874,7 +893,7 @@ JS
|
|||||||
*/
|
*/
|
||||||
public function GetObjectName($iObjId, $sFormAttCode = null)
|
public function GetObjectName($iObjId, $sFormAttCode = null)
|
||||||
{
|
{
|
||||||
$aModifierProps = array();
|
$aModifierProps = [];
|
||||||
$aModifierProps['UserRightsGetSelectFilter']['bSearchMode'] = $this->bSearchMode;
|
$aModifierProps['UserRightsGetSelectFilter']['bSearchMode'] = $this->bSearchMode;
|
||||||
|
|
||||||
$oObj = MetaModel::GetObject($this->sTargetClass, $iObjId, false, false, $aModifierProps);
|
$oObj = MetaModel::GetObject($this->sTargetClass, $iObjId, false, false, $aModifierProps);
|
||||||
@@ -884,9 +903,7 @@ JS
|
|||||||
} else {
|
} else {
|
||||||
return $oObj->Get($sFormAttCode);
|
return $oObj->Get($sFormAttCode);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -902,30 +919,29 @@ JS
|
|||||||
*/
|
*/
|
||||||
public function GetClassSelectionForm(WebPage $oPage)
|
public function GetClassSelectionForm(WebPage $oPage)
|
||||||
{
|
{
|
||||||
// For security reasons: check that the "proposed" class is actually a subclass of the linked class
|
// For security reasons: check that the "proposed" class is actually a subclass of the linked class
|
||||||
// and that the current user is allowed to create objects of this class
|
// and that the current user is allowed to create objects of this class
|
||||||
$aSubClasses = MetaModel::EnumChildClasses($this->sTargetClass, ENUM_CHILD_CLASSES_ALL);
|
$aSubClasses = MetaModel::EnumChildClasses($this->sTargetClass, ENUM_CHILD_CLASSES_ALL);
|
||||||
$aPossibleClasses = array();
|
$aPossibleClasses = [];
|
||||||
foreach($aSubClasses as $sCandidateClass)
|
foreach ($aSubClasses as $sCandidateClass) {
|
||||||
{
|
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES)) {
|
||||||
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES))
|
$aPossibleClasses[$sCandidateClass] = MetaModel::GetName($sCandidateClass);
|
||||||
{
|
}
|
||||||
$aPossibleClasses[$sCandidateClass] = MetaModel::GetName($sCandidateClass);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$sClassLabel = MetaModel::GetName($this->sTargetClass);
|
$sClassLabel = MetaModel::GetName($this->sTargetClass);
|
||||||
$sDialogTitle = Dict::Format('UI:CreationTitle_Class', $sClassLabel);;
|
$sDialogTitle = Dict::Format('UI:CreationTitle_Class', $sClassLabel);
|
||||||
$oBlock = UIContentBlockUIBlockFactory::MakeStandard('ac_create_'.$this->iId,['ibo-is-visible']);
|
;
|
||||||
|
$oBlock = UIContentBlockUIBlockFactory::MakeStandard('ac_create_'.$this->iId, ['ibo-is-visible']);
|
||||||
$oPage->AddSubBlock($oBlock);
|
$oPage->AddSubBlock($oBlock);
|
||||||
$oClassForm = FormUIBlockFactory::MakeStandard();
|
$oClassForm = FormUIBlockFactory::MakeStandard();
|
||||||
$oBlock->AddSubBlock($oClassForm);
|
$oBlock->AddSubBlock($oClassForm);
|
||||||
$oClassForm->AddSubBlock(cmdbAbstractObject::DisplayBlockSelectClassToCreate( $sClassLabel, $this->sTargetClass, $aPossibleClasses));
|
$oClassForm->AddSubBlock(cmdbAbstractObject::DisplayBlockSelectClassToCreate($sClassLabel, $this->sTargetClass, $aPossibleClasses));
|
||||||
$sDialogTitleEscaped = addslashes($sDialogTitle);
|
$sDialogTitleEscaped = addslashes($sDialogTitle);
|
||||||
$oPage->add_ready_script("$('#ac_create_$this->iId').dialog({ width: 'auto', height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true, title: '$sDialogTitleEscaped'});\n");
|
$oPage->add_ready_script("$('#ac_create_$this->iId').dialog({ width: 'auto', height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true, title: '$sDialogTitleEscaped'});\n");
|
||||||
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').removeAttr('onsubmit');");
|
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').removeAttr('onsubmit');");
|
||||||
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').find('select').attr('id', 'ac_create_{$this->iId}_select');");
|
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').find('select').attr('id', 'ac_create_{$this->iId}_select');");
|
||||||
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').on('submit.uilinksWizard', oACWidget_{$this->iId}.DoSelectObjectClass);");
|
$oPage->add_ready_script("$('#ac_create_{$this->iId} form').on('submit.uilinksWizard', oACWidget_{$this->iId}.DoSelectObjectClass);");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -941,16 +957,14 @@ JS
|
|||||||
$oAppContext->InitObjectFromContext($oNewObj);
|
$oAppContext->InitObjectFromContext($oNewObj);
|
||||||
$oNewObj->PrefillForm('creation_from_extkey', $aPrefillFormParam);
|
$oNewObj->PrefillForm('creation_from_extkey', $aPrefillFormParam);
|
||||||
// 2nd set the default values from the constraint on the external key... if any
|
// 2nd set the default values from the constraint on the external key... if any
|
||||||
if ( ($oCurrObject != null) && ($this->sAttCode != ''))
|
if (($oCurrObject != null) && ($this->sAttCode != '')) {
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oCurrObject), $this->sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef(get_class($oCurrObject), $this->sAttCode);
|
||||||
$aParams = array('this' => $oCurrObject);
|
$aParams = ['this' => $oCurrObject];
|
||||||
$oSet = $oAttDef->GetAllowedValuesAsObjectSet($aParams);
|
$oSet = $oAttDef->GetAllowedValuesAsObjectSet($aParams);
|
||||||
$aConsts = $oSet->ListConstantFields();
|
$aConsts = $oSet->ListConstantFields();
|
||||||
$sClassAlias = $oSet->GetFilter()->GetClassAlias();
|
$sClassAlias = $oSet->GetFilter()->GetClassAlias();
|
||||||
if (isset($aConsts[$sClassAlias]))
|
if (isset($aConsts[$sClassAlias])) {
|
||||||
{
|
foreach ($aConsts[$sClassAlias] as $sAttCode => $value) {
|
||||||
foreach($aConsts[$sClassAlias] as $sAttCode => $value) {
|
|
||||||
$oNewObj->Set($sAttCode, $value);
|
$oNewObj->Set($sAttCode, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -962,32 +976,35 @@ JS
|
|||||||
$sClassLabel = MetaModel::GetName($this->sTargetClass);
|
$sClassLabel = MetaModel::GetName($this->sTargetClass);
|
||||||
$sHeaderTitleEscaped = utils::EscapeHtml(Dict::Format('UI:CreationTitle_Class', $sClassLabel));
|
$sHeaderTitleEscaped = utils::EscapeHtml(Dict::Format('UI:CreationTitle_Class', $sClassLabel));
|
||||||
|
|
||||||
$oPage->add(<<<HTML
|
$oPage->add(
|
||||||
|
<<<HTML
|
||||||
<div id="ac_create_{$this->iId}" title="{$sHeaderTitleEscaped}">
|
<div id="ac_create_{$this->iId}" title="{$sHeaderTitleEscaped}">
|
||||||
<div id="dcr_{$this->iId}">
|
<div id="dcr_{$this->iId}">
|
||||||
HTML
|
HTML
|
||||||
);
|
);
|
||||||
|
|
||||||
$aFormExtraParams = array(
|
$aFormExtraParams = [
|
||||||
'formPrefix' => $this->iId,
|
'formPrefix' => $this->iId,
|
||||||
'noRelations' => true,
|
'noRelations' => true,
|
||||||
);
|
];
|
||||||
|
|
||||||
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context
|
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context
|
||||||
FormHelper::DisableAttributeBlobInputs($this->sTargetClass, $aFormExtraParams);
|
FormHelper::DisableAttributeBlobInputs($this->sTargetClass, $aFormExtraParams);
|
||||||
|
|
||||||
if(FormHelper::HasMandatoryAttributeBlobInputs($oNewObj)){
|
if (FormHelper::HasMandatoryAttributeBlobInputs($oNewObj)) {
|
||||||
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
|
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), $aFormExtraParams);
|
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, [], $aFormExtraParams);
|
||||||
$oPage->add(<<<HTML
|
$oPage->add(
|
||||||
|
<<<HTML
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
HTML
|
HTML
|
||||||
);
|
);
|
||||||
|
|
||||||
$oPage->add_ready_script(<<<JS
|
$oPage->add_ready_script(
|
||||||
|
<<<JS
|
||||||
$('#ac_create_{$this->iId}').dialog({ width: $(window).width() * 0.6, height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true});
|
$('#ac_create_{$this->iId}').dialog({ width: $(window).width() * 0.6, height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true});
|
||||||
$('#dcr_{$this->iId} form').removeAttr('onsubmit');
|
$('#dcr_{$this->iId} form').removeAttr('onsubmit');
|
||||||
$('#dcr_{$this->iId} form').find('button[type="submit"]').on('click', oACWidget_{$this->iId}.DoCreateObject);
|
$('#dcr_{$this->iId} form').find('button[type="submit"]').on('click', oACWidget_{$this->iId}.DoCreateObject);
|
||||||
@@ -1003,14 +1020,13 @@ JS
|
|||||||
$sDialogTitle = addslashes(Dict::Format('UI:HierarchyOf_Class', MetaModel::GetName($this->sTargetClass)));
|
$sDialogTitle = addslashes(Dict::Format('UI:HierarchyOf_Class', MetaModel::GetName($this->sTargetClass)));
|
||||||
$oPage->add('<div id="dlg_tree_'.$this->iId.'"><div class="wizContainer" style="vertical-align:top;"><div style="margin-bottom:5px;" id="tree_'.$this->iId.'">');
|
$oPage->add('<div id="dlg_tree_'.$this->iId.'"><div class="wizContainer" style="vertical-align:top;"><div style="margin-bottom:5px;" id="tree_'.$this->iId.'">');
|
||||||
$oPage->add('<table style="width:100%"><tr><td>');
|
$oPage->add('<table style="width:100%"><tr><td>');
|
||||||
if (is_null($sFilter))
|
if (is_null($sFilter)) {
|
||||||
{
|
|
||||||
throw new Exception('Implementation: null value for allowed values definition');
|
throw new Exception('Implementation: null value for allowed values definition');
|
||||||
}
|
}
|
||||||
|
|
||||||
$oFilter = DBObjectSearch::FromOQL($sFilter);
|
$oFilter = DBObjectSearch::FromOQL($sFilter);
|
||||||
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||||
$oSet = new DBObjectSet($oFilter, array(), array('this' => $oObj, 'current_extkey_id' => $currValue));
|
$oSet = new DBObjectSet($oFilter, [], ['this' => $oObj, 'current_extkey_id' => $currValue]);
|
||||||
|
|
||||||
$oSet->SetShowObsoleteData(utils::ShowObsoleteData());
|
$oSet->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||||
|
|
||||||
@@ -1020,17 +1036,17 @@ JS
|
|||||||
$oPage->add('</td></tr></table>');
|
$oPage->add('</td></tr></table>');
|
||||||
$oPage->add('</div>');
|
$oPage->add('</div>');
|
||||||
|
|
||||||
if ($bHasChildLeafs)
|
if ($bHasChildLeafs) {
|
||||||
{
|
|
||||||
$oPage->add('<span class="treecontrol ibo-button-group" id="treecontrolid"><a class="ibo-button ibo-is-regular ibo-is-neutral" href="?#">'.Dict::S("UI:Treeview:CollapseAll").'</a><a class="ibo-button ibo-is-regular ibo-is-neutral" href="?#">'.Dict::S("UI:Treeview:ExpandAll").'</a></span>');
|
$oPage->add('<span class="treecontrol ibo-button-group" id="treecontrolid"><a class="ibo-button ibo-is-regular ibo-is-neutral" href="?#">'.Dict::S("UI:Treeview:CollapseAll").'</a><a class="ibo-button ibo-is-regular ibo-is-neutral" href="?#">'.Dict::S("UI:Treeview:ExpandAll").'</a></span>');
|
||||||
}
|
}
|
||||||
|
|
||||||
$oPage->add('</div></div>');
|
$oPage->add('</div></div>');
|
||||||
|
|
||||||
$sOkButtonLabel = Dict::S('UI:Button:Ok');
|
$sOkButtonLabel = Dict::S('UI:Button:Ok');
|
||||||
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
||||||
$oPage->add_ready_script("\$('#tree_$this->iId ul').treeview({ control: '#treecontrolid', persist: 'false'});\n");
|
$oPage->add_ready_script("\$('#tree_$this->iId ul').treeview({ control: '#treecontrolid', persist: 'false'});\n");
|
||||||
$oPage->add_ready_script(<<<JS
|
$oPage->add_ready_script(
|
||||||
|
<<<JS
|
||||||
$('#dlg_tree_$this->iId').dialog({
|
$('#dlg_tree_$this->iId').dialog({
|
||||||
width: 'auto',
|
width: 'auto',
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
@@ -1069,8 +1085,7 @@ JS
|
|||||||
*/
|
*/
|
||||||
public function DoCreateObject($oPage)
|
public function DoCreateObject($oPage)
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
$oObj = MetaModel::NewObject($this->sTargetClass);
|
$oObj = MetaModel::NewObject($this->sTargetClass);
|
||||||
$aErrors = $oObj->UpdateObjectFromPostedForm($this->iId);
|
$aErrors = $oObj->UpdateObjectFromPostedForm($this->iId);
|
||||||
if (count($aErrors) == 0) {
|
if (count($aErrors) == 0) {
|
||||||
@@ -1088,13 +1103,12 @@ JS
|
|||||||
]);
|
]);
|
||||||
$oObj->DBInsertNoReload();
|
$oObj->DBInsertNoReload();
|
||||||
|
|
||||||
return array('name' => $oObj->GetName(), 'id' => $oObj->GetKey());
|
return ['name' => $oObj->GetName(), 'id' => $oObj->GetKey()];
|
||||||
} else {
|
} else {
|
||||||
return array('error' => implode(' ', $aErrors), 'id' => 0);
|
return ['error' => implode(' ', $aErrors), 'id' => 0];
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e) {
|
return ['error' => $e->getMessage(), 'id' => 0];
|
||||||
return array('error' => $e->getMessage(), 'id' => 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1110,32 +1124,27 @@ JS
|
|||||||
* @throws \CoreUnexpectedValue
|
* @throws \CoreUnexpectedValue
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
function DumpTree($oP, $oSet, $sParentAttCode, $currValue)
|
public function DumpTree($oP, $oSet, $sParentAttCode, $currValue)
|
||||||
{
|
{
|
||||||
$aTree = array();
|
$aTree = [];
|
||||||
$aNodes = array();
|
$aNodes = [];
|
||||||
while($oObj = $oSet->Fetch())
|
while ($oObj = $oSet->Fetch()) {
|
||||||
{
|
|
||||||
$iParentId = $oObj->Get($sParentAttCode);
|
$iParentId = $oObj->Get($sParentAttCode);
|
||||||
if (!isset($aTree[$iParentId]))
|
if (!isset($aTree[$iParentId])) {
|
||||||
{
|
$aTree[$iParentId] = [];
|
||||||
$aTree[$iParentId] = array();
|
|
||||||
}
|
}
|
||||||
$aTree[$iParentId][$oObj->GetKey()] = $oObj->GetName();
|
$aTree[$iParentId][$oObj->GetKey()] = $oObj->GetName();
|
||||||
$aNodes[$oObj->GetKey()] = $oObj;
|
$aNodes[$oObj->GetKey()] = $oObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
$aParents = array_keys($aTree);
|
$aParents = array_keys($aTree);
|
||||||
$aRoots = array();
|
$aRoots = [];
|
||||||
foreach($aParents as $id)
|
foreach ($aParents as $id) {
|
||||||
{
|
if (!array_key_exists($id, $aNodes)) {
|
||||||
if (!array_key_exists($id, $aNodes))
|
|
||||||
{
|
|
||||||
$aRoots[] = $id;
|
$aRoots[] = $id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach($aRoots as $iRootId)
|
foreach ($aRoots as $iRootId) {
|
||||||
{
|
|
||||||
$this->DumpNodes($oP, $iRootId, $aTree, $aNodes, $currValue);
|
$this->DumpNodes($oP, $iRootId, $aTree, $aNodes, $currValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1143,28 +1152,22 @@ JS
|
|||||||
return !$bHasOnlyRootNodes;
|
return !$bHasOnlyRootNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DumpNodes($oP, $iRootId, $aTree, $aNodes, $currValue)
|
public function DumpNodes($oP, $iRootId, $aTree, $aNodes, $currValue)
|
||||||
{
|
{
|
||||||
$bSelect = true;
|
$bSelect = true;
|
||||||
$bMultiple = false;
|
$bMultiple = false;
|
||||||
$sSelect = '';
|
$sSelect = '';
|
||||||
if (array_key_exists($iRootId, $aTree))
|
if (array_key_exists($iRootId, $aTree)) {
|
||||||
{
|
|
||||||
$aSortedRoots = $aTree[$iRootId];
|
$aSortedRoots = $aTree[$iRootId];
|
||||||
asort($aSortedRoots);
|
asort($aSortedRoots);
|
||||||
$oP->add("<ul>\n");
|
$oP->add("<ul>\n");
|
||||||
$fUniqueId = microtime(true);
|
$fUniqueId = microtime(true);
|
||||||
foreach($aSortedRoots as $id => $sName)
|
foreach ($aSortedRoots as $id => $sName) {
|
||||||
{
|
if ($bSelect) {
|
||||||
if ($bSelect)
|
|
||||||
{
|
|
||||||
$sChecked = ($aNodes[$id]->GetKey() == $currValue) ? 'checked' : '';
|
$sChecked = ($aNodes[$id]->GetKey() == $currValue) ? 'checked' : '';
|
||||||
if ($bMultiple)
|
if ($bMultiple) {
|
||||||
{
|
|
||||||
$sSelect = '<input id="input_'.$fUniqueId.'_'.$aNodes[$id]->GetKey().'" type="checkbox" value="'.$aNodes[$id]->GetKey().'" name="selectObject[]" '.$sChecked.'> ';
|
$sSelect = '<input id="input_'.$fUniqueId.'_'.$aNodes[$id]->GetKey().'" type="checkbox" value="'.$aNodes[$id]->GetKey().'" name="selectObject[]" '.$sChecked.'> ';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sSelect = '<input id="input_'.$fUniqueId.'_'.$aNodes[$id]->GetKey().'" type="radio" value="'.$aNodes[$id]->GetKey().'" name="selectObject" '.$sChecked.'> ';
|
$sSelect = '<input id="input_'.$fUniqueId.'_'.$aNodes[$id]->GetKey().'" type="radio" value="'.$aNodes[$id]->GetKey().'" name="selectObject" '.$sChecked.'> ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// 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
|
// 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
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -30,7 +31,7 @@ use Combodo\iTop\Renderer\BlockRenderer;
|
|||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class UIHTMLEditorWidget
|
class UIHTMLEditorWidget
|
||||||
{
|
{
|
||||||
protected $m_iId;
|
protected $m_iId;
|
||||||
protected $m_oAttDef;
|
protected $m_oAttDef;
|
||||||
@@ -41,7 +42,7 @@ class UIHTMLEditorWidget
|
|||||||
protected $m_sValidationField;
|
protected $m_sValidationField;
|
||||||
protected $m_sValue;
|
protected $m_sValue;
|
||||||
protected $m_sMandatory;
|
protected $m_sMandatory;
|
||||||
|
|
||||||
public function __construct($iInputId, $oAttDef, $sNameSuffix, $sFieldPrefix, $sHelpText, $sValidationField, $sValue, $sMandatory)
|
public function __construct($iInputId, $oAttDef, $sNameSuffix, $sFieldPrefix, $sHelpText, $sValidationField, $sValue, $sMandatory)
|
||||||
{
|
{
|
||||||
$this->m_iId = $iInputId;
|
$this->m_iId = $iInputId;
|
||||||
@@ -54,7 +55,7 @@ class UIHTMLEditorWidget
|
|||||||
$this->m_sMandatory = $sMandatory;
|
$this->m_sMandatory = $sMandatory;
|
||||||
$this->m_sFieldPrefix = $sFieldPrefix;
|
$this->m_sFieldPrefix = $sFieldPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the HTML fragment corresponding to the HTML editor widget
|
* Get the HTML fragment corresponding to the HTML editor widget
|
||||||
*
|
*
|
||||||
@@ -63,7 +64,7 @@ class UIHTMLEditorWidget
|
|||||||
*
|
*
|
||||||
* @return string The HTML fragment to be inserted into the page
|
* @return string The HTML fragment to be inserted into the page
|
||||||
*/
|
*/
|
||||||
public function Display(WebPage $oPage, array $aArgs = array()) : string
|
public function Display(WebPage $oPage, array $aArgs = []): string
|
||||||
{
|
{
|
||||||
$iId = $this->m_iId;
|
$iId = $this->m_iId;
|
||||||
$sCode = $this->m_sAttCode.$this->m_sNameSuffix;
|
$sCode = $this->m_sAttCode.$this->m_sNameSuffix;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -38,39 +39,35 @@ class UILinksWidgetDirect
|
|||||||
$this->sAttCode = $sAttCode;
|
$this->sAttCode = $sAttCode;
|
||||||
$this->sInputid = $sInputId;
|
$this->sInputid = $sInputId;
|
||||||
$this->sNameSuffix = $sNameSuffix;
|
$this->sNameSuffix = $sNameSuffix;
|
||||||
$this->aZlist = array();
|
$this->aZlist = [];
|
||||||
$this->sLinkedClass = '';
|
$this->sLinkedClass = '';
|
||||||
|
|
||||||
// Compute the list of attributes visible from the given objet:
|
// Compute the list of attributes visible from the given objet:
|
||||||
// All the attributes from the "list" Zlist of the Link class except
|
// All the attributes from the "list" Zlist of the Link class except
|
||||||
// the ExternalKey that points to the current object and its related external fields
|
// the ExternalKey that points to the current object and its related external fields
|
||||||
$oLinksetDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
$oLinksetDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
$this->sLinkedClass = $oLinksetDef->GetLinkedClass();
|
$this->sLinkedClass = $oLinksetDef->GetLinkedClass();
|
||||||
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
|
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
|
||||||
switch($oLinksetDef->GetEditMode())
|
switch ($oLinksetDef->GetEditMode()) {
|
||||||
{
|
|
||||||
case LINKSET_EDITMODE_INPLACE: // The whole linkset can be edited 'in-place'
|
case LINKSET_EDITMODE_INPLACE: // The whole linkset can be edited 'in-place'
|
||||||
$aZList = MetaModel::FlattenZList(MetaModel::GetZListItems($this->sLinkedClass, 'details'));
|
$aZList = MetaModel::FlattenZList(MetaModel::GetZListItems($this->sLinkedClass, 'details'));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$aZList = MetaModel::FlattenZList(MetaModel::GetZListItems($this->sLinkedClass, 'list'));
|
$aZList = MetaModel::FlattenZList(MetaModel::GetZListItems($this->sLinkedClass, 'list'));
|
||||||
array_unshift($aZList, 'friendlyname');
|
array_unshift($aZList, 'friendlyname');
|
||||||
}
|
}
|
||||||
foreach($aZList as $sLinkedAttCode)
|
foreach ($aZList as $sLinkedAttCode) {
|
||||||
{
|
if ($sLinkedAttCode != $sExtKeyToMe) {
|
||||||
if ($sLinkedAttCode != $sExtKeyToMe)
|
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->sLinkedClass, $sLinkedAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($this->sLinkedClass, $sLinkedAttCode);
|
||||||
|
|
||||||
if ((!$oAttDef->IsExternalField() || ($oAttDef->GetKeyAttCode() != $sExtKeyToMe)) &&
|
if ((!$oAttDef->IsExternalField() || ($oAttDef->GetKeyAttCode() != $sExtKeyToMe)) &&
|
||||||
(!$oAttDef->IsLinkSet()) )
|
(!$oAttDef->IsLinkSet())) {
|
||||||
{
|
|
||||||
$this->aZlist[] = $sLinkedAttCode;
|
$this->aZlist[] = $sLinkedAttCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -101,21 +98,17 @@ class UILinksWidgetDirect
|
|||||||
$sRealClass = '';
|
$sRealClass = '';
|
||||||
//$oPage->add('<div class="wizContainer" style="vertical-align:top;"><div>');
|
//$oPage->add('<div class="wizContainer" style="vertical-align:top;"><div>');
|
||||||
$aSubClasses = MetaModel::EnumChildClasses($this->sLinkedClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
|
$aSubClasses = MetaModel::EnumChildClasses($this->sLinkedClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
|
||||||
$aPossibleClasses = array();
|
$aPossibleClasses = [];
|
||||||
foreach($aSubClasses as $sCandidateClass)
|
foreach ($aSubClasses as $sCandidateClass) {
|
||||||
{
|
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES)) {
|
||||||
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES))
|
if ($sCandidateClass == $sProposedRealClass) {
|
||||||
{
|
|
||||||
if ($sCandidateClass == $sProposedRealClass)
|
|
||||||
{
|
|
||||||
$sRealClass = $sProposedRealClass;
|
$sRealClass = $sProposedRealClass;
|
||||||
}
|
}
|
||||||
$aPossibleClasses[$sCandidateClass] = MetaModel::GetName($sCandidateClass);
|
$aPossibleClasses[$sCandidateClass] = MetaModel::GetName($sCandidateClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Only one of the subclasses can be instantiated...
|
// Only one of the subclasses can be instantiated...
|
||||||
if (count($aPossibleClasses) == 1)
|
if (count($aPossibleClasses) == 1) {
|
||||||
{
|
|
||||||
$aKeys = array_keys($aPossibleClasses);
|
$aKeys = array_keys($aPossibleClasses);
|
||||||
$sRealClass = $aKeys[0];
|
$sRealClass = $aKeys[0];
|
||||||
}
|
}
|
||||||
@@ -123,11 +116,11 @@ class UILinksWidgetDirect
|
|||||||
if ($sRealClass != '') {
|
if ($sRealClass != '') {
|
||||||
$oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
$oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
||||||
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
|
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
|
||||||
$aFieldsFlags = array($sExtKeyToMe => OPT_ATT_HIDDEN);
|
$aFieldsFlags = [$sExtKeyToMe => OPT_ATT_HIDDEN];
|
||||||
$oObj = DBObject::MakeDefaultInstance($sRealClass);
|
$oObj = DBObject::MakeDefaultInstance($sRealClass);
|
||||||
$aPrefillParam = array('source_obj' => $oSourceObj);
|
$aPrefillParam = ['source_obj' => $oSourceObj];
|
||||||
$oObj->PrefillForm('creation_from_editinplace', $aPrefillParam);
|
$oObj->PrefillForm('creation_from_editinplace', $aPrefillParam);
|
||||||
$aFormExtraParams = array(
|
$aFormExtraParams = [
|
||||||
'formPrefix' => $this->sInputid,
|
'formPrefix' => $this->sInputid,
|
||||||
'noRelations' => true,
|
'noRelations' => true,
|
||||||
'fieldsFlags' => $aFieldsFlags,
|
'fieldsFlags' => $aFieldsFlags,
|
||||||
@@ -140,25 +133,22 @@ class UILinksWidgetDirect
|
|||||||
JS
|
JS
|
||||||
,
|
,
|
||||||
],
|
],
|
||||||
);
|
];
|
||||||
|
|
||||||
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context
|
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context
|
||||||
FormHelper::DisableAttributeBlobInputs($sRealClass, $aFormExtraParams);
|
FormHelper::DisableAttributeBlobInputs($sRealClass, $aFormExtraParams);
|
||||||
|
|
||||||
if(FormHelper::HasMandatoryAttributeBlobInputs($oObj)){
|
if (FormHelper::HasMandatoryAttributeBlobInputs($oObj)) {
|
||||||
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
|
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, array(), $aFormExtraParams);
|
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, [], $aFormExtraParams);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$sClassLabel = MetaModel::GetName($this->sLinkedClass);
|
$sClassLabel = MetaModel::GetName($this->sLinkedClass);
|
||||||
$oPage->add('<p>'.Dict::Format('UI:SelectTheTypeOf_Class_ToCreate', $sClassLabel));
|
$oPage->add('<p>'.Dict::Format('UI:SelectTheTypeOf_Class_ToCreate', $sClassLabel));
|
||||||
$oPage->add('<nobr><select name="class">');
|
$oPage->add('<nobr><select name="class">');
|
||||||
asort($aPossibleClasses);
|
asort($aPossibleClasses);
|
||||||
foreach($aPossibleClasses as $sClassName => $sClassLabel)
|
foreach ($aPossibleClasses as $sClassName => $sClassLabel) {
|
||||||
{
|
|
||||||
$oPage->add("<option value=\"$sClassName\">$sClassLabel</option>");
|
$oPage->add("<option value=\"$sClassName\">$sClassLabel</option>");
|
||||||
}
|
}
|
||||||
$oPage->add('</select>');
|
$oPage->add('</select>');
|
||||||
@@ -178,7 +168,7 @@ JS
|
|||||||
* @throws \MissingQueryArgument
|
* @throws \MissingQueryArgument
|
||||||
* @throws \OQLException
|
* @throws \OQLException
|
||||||
*/
|
*/
|
||||||
public function GetObjectsSelectionDlg($oPage, $oCurrentObj, $aAlreadyLinked, $aPrefillFormParam = array())
|
public function GetObjectsSelectionDlg($oPage, $oCurrentObj, $aAlreadyLinked, $aPrefillFormParam = [])
|
||||||
{
|
{
|
||||||
//$oPage->add("<div class=\"wizContainer\" style=\"vertical-align:top;\">\n");
|
//$oPage->add("<div class=\"wizContainer\" style=\"vertical-align:top;\">\n");
|
||||||
|
|
||||||
@@ -199,8 +189,7 @@ JS
|
|||||||
|
|
||||||
$oLinkSetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
$oLinkSetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
||||||
$valuesDef = $oLinkSetDef->GetValuesDef();
|
$valuesDef = $oLinkSetDef->GetValuesDef();
|
||||||
if ($valuesDef === null)
|
if ($valuesDef === null) {
|
||||||
{
|
|
||||||
$oFilter = new DBObjectSearch($this->sLinkedClass);
|
$oFilter = new DBObjectSearch($this->sLinkedClass);
|
||||||
} else {
|
} else {
|
||||||
if (!$valuesDef instanceof ValueSetObjects) {
|
if (!$valuesDef instanceof ValueSetObjects) {
|
||||||
@@ -218,8 +207,10 @@ JS
|
|||||||
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
||||||
}
|
}
|
||||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||||
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->sInputid}",
|
$oPage->AddUiBlock($oBlock->GetDisplay(
|
||||||
array(
|
$oPage,
|
||||||
|
"SearchFormToAdd_{$this->sInputid}",
|
||||||
|
[
|
||||||
'result_list_outer_selector' => "SearchResultsToAdd_{$this->sInputid}",
|
'result_list_outer_selector' => "SearchResultsToAdd_{$this->sInputid}",
|
||||||
'table_id' => "add_{$this->sInputid}",
|
'table_id' => "add_{$this->sInputid}",
|
||||||
'table_inner_id' => "ResultsToAdd_{$this->sInputid}",
|
'table_inner_id' => "ResultsToAdd_{$this->sInputid}",
|
||||||
@@ -227,13 +218,14 @@ JS
|
|||||||
'cssCount' => "#count_{$this->sInputid}",
|
'cssCount' => "#count_{$this->sInputid}",
|
||||||
'query_params' => $oFilter->GetInternalParams(),
|
'query_params' => $oFilter->GetInternalParams(),
|
||||||
'hidden_criteria' => $sHiddenCriteria,
|
'hidden_criteria' => $sHiddenCriteria,
|
||||||
)
|
]
|
||||||
));
|
));
|
||||||
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||||
$sCancel = Dict::S('UI:Button:Cancel');
|
$sCancel = Dict::S('UI:Button:Cancel');
|
||||||
$sAdd = Dict::S('UI:Button:Add');
|
$sAdd = Dict::S('UI:Button:Add');
|
||||||
|
|
||||||
$oPage->add(<<<HTML
|
$oPage->add(
|
||||||
|
<<<HTML
|
||||||
<form id="ObjectsAddForm_{$this->sInputid}">
|
<form id="ObjectsAddForm_{$this->sInputid}">
|
||||||
<div id="SearchResultsToAdd_{$this->sInputid}">
|
<div id="SearchResultsToAdd_{$this->sInputid}">
|
||||||
<div style="background: #fff; border:0; text-align:center; vertical-align:middle;"><p>{$sEmptyList}</p></div>
|
<div style="background: #fff; border:0; text-align:center; vertical-align:middle;"><p>{$sEmptyList}</p></div>
|
||||||
@@ -256,52 +248,43 @@ HTML
|
|||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \OQLException
|
* @throws \OQLException
|
||||||
*/
|
*/
|
||||||
public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinked = array(), $oCurrentObj = null, $aPrefillFormParam = array())
|
public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinked = [], $oCurrentObj = null, $aPrefillFormParam = [])
|
||||||
{
|
{
|
||||||
if ($sRemoteClass == '')
|
if ($sRemoteClass == '') {
|
||||||
{
|
|
||||||
$sRemoteClass = $this->sLinkedClass;
|
$sRemoteClass = $this->sLinkedClass;
|
||||||
}
|
}
|
||||||
$oLinkSetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
$oLinkSetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
||||||
$valuesDef = $oLinkSetDef->GetValuesDef();
|
$valuesDef = $oLinkSetDef->GetValuesDef();
|
||||||
if ($valuesDef === null)
|
if ($valuesDef === null) {
|
||||||
{
|
|
||||||
$oFilter = new DBObjectSearch($sRemoteClass);
|
$oFilter = new DBObjectSearch($sRemoteClass);
|
||||||
}
|
} else {
|
||||||
else
|
if (!$valuesDef instanceof ValueSetObjects) {
|
||||||
{
|
|
||||||
if (!$valuesDef instanceof ValueSetObjects)
|
|
||||||
{
|
|
||||||
throw new Exception('Error: only ValueSetObjects are supported for "allowed_values" in AttributeLinkedSet ('.$this->sClass.'/'.$this->sAttCode.').');
|
throw new Exception('Error: only ValueSetObjects are supported for "allowed_values" in AttributeLinkedSet ('.$this->sClass.'/'.$this->sAttCode.').');
|
||||||
}
|
}
|
||||||
$oFilter = DBObjectSearch::FromOQL($valuesDef->GetFilterExpression());
|
$oFilter = DBObjectSearch::FromOQL($valuesDef->GetFilterExpression());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($oCurrentObj != null) && MetaModel::IsSameFamilyBranch($sRemoteClass, $this->sClass))
|
if (($oCurrentObj != null) && MetaModel::IsSameFamilyBranch($sRemoteClass, $this->sClass)) {
|
||||||
{
|
|
||||||
// Prevent linking to self if the linked object is of the same family
|
// Prevent linking to self if the linked object is of the same family
|
||||||
// and already present in the database
|
// and already present in the database
|
||||||
if (!$oCurrentObj->IsNew())
|
if (!$oCurrentObj->IsNew()) {
|
||||||
{
|
|
||||||
$oFilter->AddCondition('id', $oCurrentObj->GetKey(), '!=');
|
$oFilter->AddCondition('id', $oCurrentObj->GetKey(), '!=');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($oCurrentObj != null)
|
if ($oCurrentObj != null) {
|
||||||
{
|
|
||||||
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
||||||
|
|
||||||
$aArgs = array_merge($oCurrentObj->ToArgs('this'), $oFilter->GetInternalParams());
|
$aArgs = array_merge($oCurrentObj->ToArgs('this'), $oFilter->GetInternalParams());
|
||||||
$oFilter->SetInternalParams($aArgs);
|
$oFilter->SetInternalParams($aArgs);
|
||||||
|
|
||||||
$aPrefillFormParam['filter'] = $oFilter;
|
$aPrefillFormParam['filter'] = $oFilter;
|
||||||
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
||||||
}
|
}
|
||||||
if (count($aAlreadyLinked) > 0)
|
if (count($aAlreadyLinked) > 0) {
|
||||||
{
|
|
||||||
$oFilter->AddCondition('id', $aAlreadyLinked, 'NOTIN');
|
$oFilter->AddCondition('id', $aAlreadyLinked, 'NOTIN');
|
||||||
}
|
}
|
||||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||||
$oBlock->Display($oP, "ResultsToAdd_{$this->sInputid}", array('menu' => false, 'cssCount'=> '#count_'.$this->sInputid , 'selection_mode' => true, 'table_id' => 'add_'.$this->sInputid)); // Don't display the 'Actions' menu on the results
|
$oBlock->Display($oP, "ResultsToAdd_{$this->sInputid}", ['menu' => false, 'cssCount' => '#count_'.$this->sInputid , 'selection_mode' => true, 'table_id' => 'add_'.$this->sInputid]); // Don't display the 'Actions' menu on the results
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -311,29 +294,28 @@ HTML
|
|||||||
public function DoAddObjects(WebPage $oP, $oFullSetFilter)
|
public function DoAddObjects(WebPage $oP, $oFullSetFilter)
|
||||||
{
|
{
|
||||||
$aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter);
|
$aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter);
|
||||||
foreach($aLinkedObjectIds as $iObjectId)
|
foreach ($aLinkedObjectIds as $iObjectId) {
|
||||||
{
|
|
||||||
$oLinkObj = MetaModel::GetObject($this->sLinkedClass, $iObjectId);
|
$oLinkObj = MetaModel::GetObject($this->sLinkedClass, $iObjectId);
|
||||||
$oP->add($this->GetObjectRow($oP, $oLinkObj, $oLinkObj->GetKey()));
|
$oP->add($this->GetObjectRow($oP, $oLinkObj, $oLinkObj->GetKey()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetObjectModificationDlg()
|
public function GetObjectModificationDlg()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetTableConfig()
|
public function GetTableConfig()
|
||||||
{
|
{
|
||||||
$aAttribs = array();
|
$aAttribs = [];
|
||||||
$aAttribs['form::select'] = array(
|
$aAttribs['form::select'] = [
|
||||||
'label' => "<input type=\"checkbox\" onClick=\"CheckAll('.selectList{$this->sInputid}:not(:disabled)', this.checked);oWidget".$this->sInputid.".directlinks('instance')._onSelectChange();\" class=\"checkAll\"></input>",
|
'label' => "<input type=\"checkbox\" onClick=\"CheckAll('.selectList{$this->sInputid}:not(:disabled)', this.checked);oWidget".$this->sInputid.".directlinks('instance')._onSelectChange();\" class=\"checkAll\"></input>",
|
||||||
'description' => Dict::S('UI:SelectAllToggle+'),
|
'description' => Dict::S('UI:SelectAllToggle+'),
|
||||||
);
|
];
|
||||||
|
|
||||||
foreach ($this->aZlist as $sLinkedAttCode) {
|
foreach ($this->aZlist as $sLinkedAttCode) {
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->sLinkedClass, $sLinkedAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($this->sLinkedClass, $sLinkedAttCode);
|
||||||
$aAttribs[$sLinkedAttCode] = array('label' => MetaModel::GetLabel($this->sLinkedClass, $sLinkedAttCode), 'description' => $oAttDef->GetOrderByHint());
|
$aAttribs[$sLinkedAttCode] = ['label' => MetaModel::GetLabel($this->sLinkedClass, $sLinkedAttCode), 'description' => $oAttDef->GetOrderByHint()];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $aAttribs;
|
return $aAttribs;
|
||||||
@@ -348,13 +330,12 @@ HTML
|
|||||||
*/
|
*/
|
||||||
public function GetRow($oPage, $sRealClass, $aValues, $iTempId)
|
public function GetRow($oPage, $sRealClass, $aValues, $iTempId)
|
||||||
{
|
{
|
||||||
if ($sRealClass == '')
|
if ($sRealClass == '') {
|
||||||
{
|
|
||||||
$sRealClass = $this->sLinkedClass;
|
$sRealClass = $this->sLinkedClass;
|
||||||
}
|
}
|
||||||
$oLinkObj = new $sRealClass();
|
$oLinkObj = new $sRealClass();
|
||||||
$oLinkObj->UpdateObjectFromPostedForm($this->sInputid);
|
$oLinkObj->UpdateObjectFromPostedForm($this->sInputid);
|
||||||
|
|
||||||
return $this->GetObjectRow($oPage, $oLinkObj, $iTempId);
|
return $this->GetObjectRow($oPage, $oLinkObj, $iTempId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,13 +348,12 @@ HTML
|
|||||||
protected function GetObjectRow($oPage, $oLinkObj, $iTempId)
|
protected function GetObjectRow($oPage, $oLinkObj, $iTempId)
|
||||||
{
|
{
|
||||||
$aAttribs = $this->GetTableConfig();
|
$aAttribs = $this->GetTableConfig();
|
||||||
$aRow = array();
|
$aRow = [];
|
||||||
$aRow['form::select'] = '<input type="checkbox" class="selectList'.$this->sInputid.'" value="'.($iTempId).'"/>';
|
$aRow['form::select'] = '<input type="checkbox" class="selectList'.$this->sInputid.'" value="'.($iTempId).'"/>';
|
||||||
foreach($this->aZlist as $sLinkedAttCode)
|
foreach ($this->aZlist as $sLinkedAttCode) {
|
||||||
{
|
|
||||||
$aRow[$sLinkedAttCode] = $oLinkObj->GetAsHTML($sLinkedAttCode);
|
$aRow[$sLinkedAttCode] = $oLinkObj->GetAsHTML($sLinkedAttCode);
|
||||||
}
|
}
|
||||||
return $oPage->GetTableRow($aRow, $aAttribs);
|
return $oPage->GetTableRow($aRow, $aAttribs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -386,23 +366,21 @@ HTML
|
|||||||
*/
|
*/
|
||||||
public function GetFormRow($oPage, $sRealClass, $aValues, $iTempId)
|
public function GetFormRow($oPage, $sRealClass, $aValues, $iTempId)
|
||||||
{
|
{
|
||||||
if ($sRealClass == '')
|
if ($sRealClass == '') {
|
||||||
{
|
|
||||||
$sRealClass = $this->sLinkedClass;
|
$sRealClass = $this->sLinkedClass;
|
||||||
}
|
}
|
||||||
$oLinkObj = new $sRealClass();
|
$oLinkObj = new $sRealClass();
|
||||||
$oLinkObj->UpdateObjectFromPostedForm($this->sInputid);
|
$oLinkObj->UpdateObjectFromPostedForm($this->sInputid);
|
||||||
|
|
||||||
$aAttribs = $this->GetTableConfig();
|
$aAttribs = $this->GetTableConfig();
|
||||||
$aRow = array();
|
$aRow = [];
|
||||||
$aRow[] = '<input type="checkbox" class="selectList'.$this->sInputid.'" value="'.($iTempId).'"/>';
|
$aRow[] = '<input type="checkbox" class="selectList'.$this->sInputid.'" value="'.($iTempId).'"/>';
|
||||||
foreach($this->aZlist as $sLinkedAttCode)
|
foreach ($this->aZlist as $sLinkedAttCode) {
|
||||||
{
|
|
||||||
$aRow[] = $oLinkObj->GetAsHTML($sLinkedAttCode);
|
$aRow[] = $oLinkObj->GetAsHTML($sLinkedAttCode);
|
||||||
}
|
}
|
||||||
return $aRow;
|
return $aRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the default search parameters based on 1) a 'current' object and 2) the silos defined by the context
|
* Initializes the default search parameters based on 1) a 'current' object and 2) the silos defined by the context
|
||||||
* @param DBObject $oSourceObj
|
* @param DBObject $oSourceObj
|
||||||
@@ -413,27 +391,23 @@ HTML
|
|||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sSrcClass = get_class($oSourceObj);
|
$sSrcClass = get_class($oSourceObj);
|
||||||
$sDestClass = $oSearch->GetClass();
|
$sDestClass = $oSearch->GetClass();
|
||||||
foreach($oAppContext->GetNames() as $key)
|
foreach ($oAppContext->GetNames() as $key) {
|
||||||
{
|
|
||||||
// Find the value of the object corresponding to each 'context' parameter
|
// Find the value of the object corresponding to each 'context' parameter
|
||||||
$aCallSpec = array($sSrcClass, 'MapContextParam');
|
$aCallSpec = [$sSrcClass, 'MapContextParam'];
|
||||||
$sAttCode = '';
|
$sAttCode = '';
|
||||||
if (is_callable($aCallSpec))
|
if (is_callable($aCallSpec)) {
|
||||||
{
|
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MetaModel::IsValidAttCode($sSrcClass, $sAttCode))
|
if (MetaModel::IsValidAttCode($sSrcClass, $sAttCode)) {
|
||||||
{
|
|
||||||
$defaultValue = $oSourceObj->Get($sAttCode);
|
$defaultValue = $oSourceObj->Get($sAttCode);
|
||||||
|
|
||||||
// Find the attcode for the same 'context' parameter in the destination class
|
// Find the attcode for the same 'context' parameter in the destination class
|
||||||
// and sets its value as the default value for the search condition
|
// and sets its value as the default value for the search condition
|
||||||
$aCallSpec = array($sDestClass, 'MapContextParam');
|
$aCallSpec = [$sDestClass, 'MapContextParam'];
|
||||||
$sAttCode = '';
|
$sAttCode = '';
|
||||||
if (is_callable($aCallSpec))
|
if (is_callable($aCallSpec)) {
|
||||||
{
|
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MetaModel::IsValidAttCode($sDestClass, $sAttCode) && !empty($defaultValue)) {
|
if (MetaModel::IsValidAttCode($sDestClass, $sAttCode) && !empty($defaultValue)) {
|
||||||
@@ -443,7 +417,6 @@ HTML
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function GetClass(): string
|
public function GetClass(): string
|
||||||
{
|
{
|
||||||
return $this->sClass;
|
return $this->sClass;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -54,7 +55,7 @@ class UILinksWidget
|
|||||||
$this->m_sNameSuffix = $sNameSuffix;
|
$this->m_sNameSuffix = $sNameSuffix;
|
||||||
$this->m_bDuplicatesAllowed = $bDuplicatesAllowed;
|
$this->m_bDuplicatesAllowed = $bDuplicatesAllowed;
|
||||||
|
|
||||||
$this->m_aEditableFields = array();
|
$this->m_aEditableFields = [];
|
||||||
|
|
||||||
/** @var AttributeLinkedSetIndirect $oAttDef */
|
/** @var AttributeLinkedSetIndirect $oAttDef */
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sAttCode);
|
||||||
@@ -67,34 +68,33 @@ class UILinksWidget
|
|||||||
$oLinkingAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $this->m_sExtKeyToRemote);
|
$oLinkingAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $this->m_sExtKeyToRemote);
|
||||||
$this->m_sRemoteClass = $oLinkingAttDef->GetTargetClass();
|
$this->m_sRemoteClass = $oLinkingAttDef->GetTargetClass();
|
||||||
|
|
||||||
$this->m_aEditableFields = array();
|
$this->m_aEditableFields = [];
|
||||||
$this->m_aTableConfig = array();
|
$this->m_aTableConfig = [];
|
||||||
$this->m_aTableConfig['form::checkbox'] = array(
|
$this->m_aTableConfig['form::checkbox'] = [
|
||||||
'label' => "<input class=\"select_all\" type=\"checkbox\" value=\"1\" onClick=\"CheckAll('#linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix} .selection', this.checked); oWidget".$this->m_sInputId.".OnSelectChange();\">",
|
'label' => "<input class=\"select_all\" type=\"checkbox\" value=\"1\" onClick=\"CheckAll('#linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix} .selection', this.checked); oWidget".$this->m_sInputId.".OnSelectChange();\">",
|
||||||
'description' => Dict::S('UI:SelectAllToggle+'),
|
'description' => Dict::S('UI:SelectAllToggle+'),
|
||||||
);
|
];
|
||||||
|
|
||||||
$aLnkAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectLinkClass($sClass, $sAttCode);
|
$aLnkAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectLinkClass($sClass, $sAttCode);
|
||||||
foreach ($aLnkAttDefsToDisplay as $oLnkAttDef)
|
foreach ($aLnkAttDefsToDisplay as $oLnkAttDef) {
|
||||||
{
|
|
||||||
$sLnkAttCode = $oLnkAttDef->GetCode();
|
$sLnkAttCode = $oLnkAttDef->GetCode();
|
||||||
$this->m_aEditableFields[] = $sLnkAttCode;
|
$this->m_aEditableFields[] = $sLnkAttCode;
|
||||||
$this->m_aTableConfig[$sLnkAttCode] = array('label' => $oLnkAttDef->GetLabel(), 'description' => $oLnkAttDef->GetDescription());
|
$this->m_aTableConfig[$sLnkAttCode] = ['label' => $oLnkAttDef->GetLabel(), 'description' => $oLnkAttDef->GetDescription()];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->m_aTableConfig['static::key'] = array(
|
$this->m_aTableConfig['static::key'] = [
|
||||||
'label' => MetaModel::GetName($this->m_sRemoteClass),
|
'label' => MetaModel::GetName($this->m_sRemoteClass),
|
||||||
'description' => MetaModel::GetClassDescription($this->m_sRemoteClass),
|
'description' => MetaModel::GetClassDescription($this->m_sRemoteClass),
|
||||||
);
|
];
|
||||||
$this->m_aEditableFields[] = $this->m_sExtKeyToRemote;
|
$this->m_aEditableFields[] = $this->m_sExtKeyToRemote;
|
||||||
|
|
||||||
$aRemoteAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectRemoteClass($this->m_sRemoteClass);
|
$aRemoteAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectRemoteClass($this->m_sRemoteClass);
|
||||||
foreach ($aRemoteAttDefsToDisplay as $oRemoteAttDef) {
|
foreach ($aRemoteAttDefsToDisplay as $oRemoteAttDef) {
|
||||||
$sRemoteAttCode = $oRemoteAttDef->GetCode();
|
$sRemoteAttCode = $oRemoteAttDef->GetCode();
|
||||||
$this->m_aTableConfig['static::'.$sRemoteAttCode] = array(
|
$this->m_aTableConfig['static::'.$sRemoteAttCode] = [
|
||||||
'label' => $oRemoteAttDef->GetLabel(),
|
'label' => $oRemoteAttDef->GetLabel(),
|
||||||
'description' => $oRemoteAttDef->GetDescription(),
|
'description' => $oRemoteAttDef->GetDescription(),
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +105,6 @@ class UILinksWidget
|
|||||||
return ($bSafe) ? utils::GetSafeId($sFieldId) : $sFieldId;
|
return ($bSafe) ? utils::GetSafeId($sFieldId) : $sFieldId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the table with the form for editing all the links at once
|
* Display the table with the form for editing all the links at once
|
||||||
*
|
*
|
||||||
@@ -119,7 +118,6 @@ class UILinksWidget
|
|||||||
return DataTableUIBlockFactory::MakeForForm("{$this->m_sAttCode}{$this->m_sNameSuffix}", $aConfig, $aData);
|
return DataTableUIBlockFactory::MakeForForm("{$this->m_sAttCode}{$this->m_sNameSuffix}", $aConfig, $aData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the HTML fragment corresponding to the linkset editing widget
|
* Get the HTML fragment corresponding to the linkset editing widget
|
||||||
*
|
*
|
||||||
@@ -157,7 +155,7 @@ class UILinksWidget
|
|||||||
* @throws DictExceptionMissingString
|
* @throws DictExceptionMissingString
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function GetObjectPickerDialog($oPage, $oCurrentObj, $sJson, $aAlreadyLinkedIds = array(), $aPrefillFormParam = array())
|
public function GetObjectPickerDialog($oPage, $oCurrentObj, $sJson, $aAlreadyLinkedIds = [], $aPrefillFormParam = [])
|
||||||
{
|
{
|
||||||
$oAlreadyLinkedFilter = new DBObjectSearch($this->m_sRemoteClass);
|
$oAlreadyLinkedFilter = new DBObjectSearch($this->m_sRemoteClass);
|
||||||
if (!$this->m_bDuplicatesAllowed && count($aAlreadyLinkedIds) > 0) {
|
if (!$this->m_bDuplicatesAllowed && count($aAlreadyLinkedIds) > 0) {
|
||||||
@@ -183,7 +181,9 @@ class UILinksWidget
|
|||||||
$sLinkedSetId = $oBlock->oUILinksWidget->GetLinkedSetId();
|
$sLinkedSetId = $oBlock->oUILinksWidget->GetLinkedSetId();
|
||||||
|
|
||||||
$oDisplayBlock = new DisplayBlock($oFilter, 'search', false);
|
$oDisplayBlock = new DisplayBlock($oFilter, 'search', false);
|
||||||
$oBlock->AddSubBlock($oDisplayBlock->GetDisplay($oPage, "SearchFormToAdd_{$sLinkedSetId}",
|
$oBlock->AddSubBlock($oDisplayBlock->GetDisplay(
|
||||||
|
$oPage,
|
||||||
|
"SearchFormToAdd_{$sLinkedSetId}",
|
||||||
[
|
[
|
||||||
'menu' => false,
|
'menu' => false,
|
||||||
'result_list_outer_selector' => "SearchResultsToAdd_{$sLinkedSetId}",
|
'result_list_outer_selector' => "SearchResultsToAdd_{$sLinkedSetId}",
|
||||||
@@ -195,7 +195,8 @@ class UILinksWidget
|
|||||||
'query_params' => $oFilter->GetInternalParams(),
|
'query_params' => $oFilter->GetInternalParams(),
|
||||||
'hidden_criteria' => $sAlreadyLinkedExpression,
|
'hidden_criteria' => $sAlreadyLinkedExpression,
|
||||||
'submit_on_load' => false,
|
'submit_on_load' => false,
|
||||||
]));
|
]
|
||||||
|
));
|
||||||
|
|
||||||
$oBlock->AddForm();
|
$oBlock->AddForm();
|
||||||
}
|
}
|
||||||
@@ -212,25 +213,21 @@ class UILinksWidget
|
|||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinkedIds = array(), $oCurrentObj = null)
|
public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinkedIds = [], $oCurrentObj = null)
|
||||||
{
|
{
|
||||||
if ($sRemoteClass != '')
|
if ($sRemoteClass != '') {
|
||||||
{
|
|
||||||
// assert(MetaModel::IsParentClass($this->m_sRemoteClass, $sRemoteClass));
|
// assert(MetaModel::IsParentClass($this->m_sRemoteClass, $sRemoteClass));
|
||||||
$oFilter = new DBObjectSearch($sRemoteClass);
|
$oFilter = new DBObjectSearch($sRemoteClass);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// No remote class specified use the one defined in the linkedset
|
// No remote class specified use the one defined in the linkedset
|
||||||
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
||||||
}
|
}
|
||||||
if (!$this->m_bDuplicatesAllowed && count($aAlreadyLinkedIds) > 0)
|
if (!$this->m_bDuplicatesAllowed && count($aAlreadyLinkedIds) > 0) {
|
||||||
{
|
|
||||||
$oFilter->AddCondition('id', $aAlreadyLinkedIds, 'NOTIN');
|
$oFilter->AddCondition('id', $aAlreadyLinkedIds, 'NOTIN');
|
||||||
}
|
}
|
||||||
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
||||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||||
$oBlock->Display($oP, "ResultsToAdd_{$this->m_sAttCode}", array('menu' => false, 'cssCount'=> '#count_'.$this->m_sAttCode.$this->m_sNameSuffix , 'selection_mode' => true, 'table_id' => 'add_'.$this->m_sAttCode)); // Don't display the 'Actions' menu on the results
|
$oBlock->Display($oP, "ResultsToAdd_{$this->m_sAttCode}", ['menu' => false, 'cssCount' => '#count_'.$this->m_sAttCode.$this->m_sNameSuffix , 'selection_mode' => true, 'table_id' => 'add_'.$this->m_sAttCode]); // Don't display the 'Actions' menu on the results
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -251,7 +248,7 @@ class UILinksWidget
|
|||||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
|
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
|
||||||
if (is_object($oLinkedObj)) {
|
if (is_object($oLinkedObj)) {
|
||||||
$oBlock = new BlockIndirectLinkSetEditTable($this);
|
$oBlock = new BlockIndirectLinkSetEditTable($this);
|
||||||
$aRow = $oBlock->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids
|
$aRow = $oBlock->GetFormRow($oP, $oLinkedObj, $iObjectId, [], $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids
|
||||||
$oRow = new FormTableRow("{$this->m_sAttCode}{$this->m_sNameSuffix}", $this->m_aTableConfig, $aRow, -$iAdditionId);
|
$oRow = new FormTableRow("{$this->m_sAttCode}{$this->m_sNameSuffix}", $this->m_aTableConfig, $aRow, -$iAdditionId);
|
||||||
$oP->AddUiBlock($oRow);
|
$oP->AddUiBlock($oRow);
|
||||||
$iAdditionId++;
|
$iAdditionId++;
|
||||||
@@ -280,7 +277,7 @@ class UILinksWidget
|
|||||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
|
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
|
||||||
if (is_object($oLinkedObj)) {
|
if (is_object($oLinkedObj)) {
|
||||||
$oBlock = new BlockIndirectLinkSetEditTable($this);
|
$oBlock = new BlockIndirectLinkSetEditTable($this);
|
||||||
$aRow = $oBlock->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId, false /* Default value */, $bAllowRemoteExtKeyEdit); // Not yet created link get negative Ids
|
$aRow = $oBlock->GetFormRow($oP, $oLinkedObj, $iObjectId, [], $oCurrentObj, $iAdditionId, false /* Default value */, $bAllowRemoteExtKeyEdit); // Not yet created link get negative Ids
|
||||||
$aData = [];
|
$aData = [];
|
||||||
foreach ($aRow as $item) {
|
foreach ($aRow as $item) {
|
||||||
$aData[] = $item;
|
$aData[] = $item;
|
||||||
@@ -307,37 +304,30 @@ class UILinksWidget
|
|||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sSrcClass = get_class($oSourceObj);
|
$sSrcClass = get_class($oSourceObj);
|
||||||
$sDestClass = $oSearch->GetClass();
|
$sDestClass = $oSearch->GetClass();
|
||||||
foreach($oAppContext->GetNames() as $key)
|
foreach ($oAppContext->GetNames() as $key) {
|
||||||
{
|
|
||||||
// Find the value of the object corresponding to each 'context' parameter
|
// Find the value of the object corresponding to each 'context' parameter
|
||||||
$aCallSpec = array($sSrcClass, 'MapContextParam');
|
$aCallSpec = [$sSrcClass, 'MapContextParam'];
|
||||||
$sAttCode = '';
|
$sAttCode = '';
|
||||||
if (is_callable($aCallSpec))
|
if (is_callable($aCallSpec)) {
|
||||||
{
|
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MetaModel::IsValidAttCode($sSrcClass, $sAttCode))
|
if (MetaModel::IsValidAttCode($sSrcClass, $sAttCode)) {
|
||||||
{
|
|
||||||
$defaultValue = $oSourceObj->Get($sAttCode);
|
$defaultValue = $oSourceObj->Get($sAttCode);
|
||||||
|
|
||||||
// Find the attcode for the same 'context' parameter in the destination class
|
// Find the attcode for the same 'context' parameter in the destination class
|
||||||
// and sets its value as the default value for the search condition
|
// and sets its value as the default value for the search condition
|
||||||
$aCallSpec = array($sDestClass, 'MapContextParam');
|
$aCallSpec = [$sDestClass, 'MapContextParam'];
|
||||||
$sAttCode = '';
|
$sAttCode = '';
|
||||||
if (is_callable($aCallSpec))
|
if (is_callable($aCallSpec)) {
|
||||||
{
|
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MetaModel::IsValidAttCode($sDestClass, $sAttCode) && !empty($defaultValue))
|
if (MetaModel::IsValidAttCode($sDestClass, $sAttCode) && !empty($defaultValue)) {
|
||||||
{
|
|
||||||
// Add Hierarchical condition if hierarchical key
|
// Add Hierarchical condition if hierarchical key
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sDestClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sDestClass, $sAttCode);
|
||||||
if (isset($oAttDef) && ($oAttDef->IsExternalKey()))
|
if (isset($oAttDef) && ($oAttDef->IsExternalKey())) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
/** @var AttributeExternalKey $oAttDef */
|
/** @var AttributeExternalKey $oAttDef */
|
||||||
$sTargetClass = $oAttDef->GetTargetClass();
|
$sTargetClass = $oAttDef->GetTargetClass();
|
||||||
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($sTargetClass);
|
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($sTargetClass);
|
||||||
@@ -348,8 +338,7 @@ class UILinksWidget
|
|||||||
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW);
|
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW);
|
||||||
$oSearch->AddCondition_PointingTo($oHKFilter, $sAttCode);
|
$oSearch->AddCondition_PointingTo($oHKFilter, $sAttCode);
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e) {
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$oSearch->AddCondition($sAttCode, $defaultValue);
|
$oSearch->AddCondition($sAttCode, $defaultValue);
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// 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
|
// 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
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -28,13 +29,13 @@ use Combodo\iTop\Application\WebPage\WebPage;
|
|||||||
|
|
||||||
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
||||||
|
|
||||||
class UIPasswordWidget
|
class UIPasswordWidget
|
||||||
{
|
{
|
||||||
protected static $iWidgetIndex = 0;
|
protected static $iWidgetIndex = 0;
|
||||||
protected $sAttCode;
|
protected $sAttCode;
|
||||||
protected $sNameSuffix;
|
protected $sNameSuffix;
|
||||||
protected $iId;
|
protected $iId;
|
||||||
|
|
||||||
public function __construct($sAttCode, $iInputId, $sNameSuffix = '')
|
public function __construct($sAttCode, $iInputId, $sNameSuffix = '')
|
||||||
{
|
{
|
||||||
self::$iWidgetIndex++;
|
self::$iWidgetIndex++;
|
||||||
@@ -42,14 +43,14 @@ class UIPasswordWidget
|
|||||||
$this->sNameSuffix = $sNameSuffix;
|
$this->sNameSuffix = $sNameSuffix;
|
||||||
$this->iId = $iInputId;
|
$this->iId = $iInputId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the HTML fragment corresponding to the linkset editing widget
|
* Get the HTML fragment corresponding to the linkset editing widget
|
||||||
* @param WebPage $oP The web page used for all the output
|
* @param WebPage $oP The web page used for all the output
|
||||||
* @param Hash $aArgs Extra context arguments
|
* @param Hash $aArgs Extra context arguments
|
||||||
* @return string The HTML fragment to be inserted into the page
|
* @return string The HTML fragment to be inserted into the page
|
||||||
*/
|
*/
|
||||||
public function Display(WebPage $oPage, $aArgs = array())
|
public function Display(WebPage $oPage, $aArgs = [])
|
||||||
{
|
{
|
||||||
$oPage->add_dict_entry('UI:Component:Input:Password:DoesNotMatch');
|
$oPage->add_dict_entry('UI:Component:Input:Password:DoesNotMatch');
|
||||||
|
|
||||||
@@ -94,4 +95,3 @@ class UIPasswordWidget
|
|||||||
return $sHtmlValue;
|
return $sHtmlValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2024 Combodo SAS
|
* Copyright (C) 2010-2024 Combodo SAS
|
||||||
@@ -20,7 +21,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
use Combodo\iTop\Application\WebPage\WebPage;
|
use Combodo\iTop\Application\WebPage\WebPage;
|
||||||
|
|
||||||
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
require_once(APPROOT.'/application/displayblock.class.inc.php');
|
||||||
@@ -46,8 +46,10 @@ class UISearchFormForeignKeys
|
|||||||
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
||||||
|
|
||||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||||
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->m_iInputId}",
|
$oPage->AddUiBlock($oBlock->GetDisplay(
|
||||||
array(
|
$oPage,
|
||||||
|
"SearchFormToAdd_{$this->m_iInputId}",
|
||||||
|
[
|
||||||
'menu' => false,
|
'menu' => false,
|
||||||
'result_list_outer_selector' => "SearchResultsToAdd_{$this->m_iInputId}",
|
'result_list_outer_selector' => "SearchResultsToAdd_{$this->m_iInputId}",
|
||||||
'table_id' => "add_{$this->m_iInputId}",
|
'table_id' => "add_{$this->m_iInputId}",
|
||||||
@@ -55,12 +57,14 @@ class UISearchFormForeignKeys
|
|||||||
'selection_mode' => true,
|
'selection_mode' => true,
|
||||||
'cssCount' => "#count_{$this->m_iInputId}",
|
'cssCount' => "#count_{$this->m_iInputId}",
|
||||||
'query_params' => $oFilter->GetInternalParams(),
|
'query_params' => $oFilter->GetInternalParams(),
|
||||||
)));
|
]
|
||||||
|
));
|
||||||
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||||
$sCancel = Dict::S('UI:Button:Cancel');
|
$sCancel = Dict::S('UI:Button:Cancel');
|
||||||
$sAdd = Dict::S('UI:Button:Add');
|
$sAdd = Dict::S('UI:Button:Add');
|
||||||
|
|
||||||
$oPage->add(<<<HTML
|
$oPage->add(
|
||||||
|
<<<HTML
|
||||||
<form id="ObjectsAddForm_{$this->m_iInputId}">
|
<form id="ObjectsAddForm_{$this->m_iInputId}">
|
||||||
<div id="SearchResultsToAdd_{$this->m_iInputId}" style="vertical-align:top;height:100%;overflow:auto;padding:0;border:0;">
|
<div id="SearchResultsToAdd_{$this->m_iInputId}" style="vertical-align:top;height:100%;overflow:auto;padding:0;border:0;">
|
||||||
<div style="background: #fff; border:0; text-align:center; vertical-align:middle;"><p>{$sEmptyList}</p></div>
|
<div style="background: #fff; border:0; text-align:center; vertical-align:middle;"><p>{$sEmptyList}</p></div>
|
||||||
@@ -101,20 +105,17 @@ $('#dlg_{$this->m_iInputId}').dialog('option', {title:'$sTitle'});
|
|||||||
$('#SearchFormToAdd_{$this->m_iInputId} form').on('submit.uilinksWizard', oForeignKeysWidget{$this->m_iInputId}.SearchObjectsToAdd);
|
$('#SearchFormToAdd_{$this->m_iInputId} form').on('submit.uilinksWizard', oForeignKeysWidget{$this->m_iInputId}.SearchObjectsToAdd);
|
||||||
$('#SearchFormToAdd_{$this->m_iInputId}').on('resize', oForeignKeysWidget{$this->m_iInputId}.UpdateSizes);
|
$('#SearchFormToAdd_{$this->m_iInputId}').on('resize', oForeignKeysWidget{$this->m_iInputId}.UpdateSizes);
|
||||||
JS
|
JS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetFullListForeignKeysFromSelection($oPage, $oFullSetFilter)
|
public function GetFullListForeignKeysFromSelection($oPage, $oFullSetFilter)
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
$aLinkedObjects = utils::ReadMultipleSelectionWithFriendlyname($oFullSetFilter);
|
$aLinkedObjects = utils::ReadMultipleSelectionWithFriendlyname($oFullSetFilter);
|
||||||
$oPage->add(json_encode($aLinkedObjects));
|
$oPage->add(json_encode($aLinkedObjects));
|
||||||
}
|
} catch (CoreException $e) {
|
||||||
catch (CoreException $e)
|
|
||||||
{
|
|
||||||
http_response_code(500);
|
http_response_code(500);
|
||||||
$oPage->add(json_encode(array('error' => $e->GetMessage())));
|
$oPage->add(json_encode(['error' => $e->GetMessage()]));
|
||||||
IssueLog::Error($e->getMessage()."\nDebug trace:\n".$e->getTraceAsString());
|
IssueLog::Error($e->getMessage()."\nDebug trace:\n".$e->getTraceAsString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,20 +130,20 @@ JS
|
|||||||
*/
|
*/
|
||||||
public function ListResultsSearchForeignKeys(WebPage $oP, $sRemoteClass = '')
|
public function ListResultsSearchForeignKeys(WebPage $oP, $sRemoteClass = '')
|
||||||
{
|
{
|
||||||
if ($sRemoteClass != '')
|
if ($sRemoteClass != '') {
|
||||||
{
|
|
||||||
// assert(MetaModel::IsParentClass($this->m_sRemoteClass, $sRemoteClass));
|
// assert(MetaModel::IsParentClass($this->m_sRemoteClass, $sRemoteClass));
|
||||||
$oFilter = new DBObjectSearch($sRemoteClass);
|
$oFilter = new DBObjectSearch($sRemoteClass);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// No remote class specified use the one defined in the linkedset
|
// No remote class specified use the one defined in the linkedset
|
||||||
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||||
$oBlock->Display($oP, "ResultsToAdd_{$this->m_iInputId}",
|
$oBlock->Display(
|
||||||
array('menu' => false, 'cssCount' => "#count_{$this->m_iInputId}", 'selection_mode' => true, 'table_id' => "add_{$this->m_iInputId}"));
|
$oP,
|
||||||
|
"ResultsToAdd_{$this->m_iInputId}",
|
||||||
|
['menu' => false, 'cssCount' => "#count_{$this->m_iInputId}", 'selection_mode' => true, 'table_id' => "add_{$this->m_iInputId}"]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// 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
|
// 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
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -17,7 +18,6 @@
|
|||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class UIWizard
|
* Class UIWizard
|
||||||
*
|
*
|
||||||
@@ -31,74 +31,73 @@ class UIWizard
|
|||||||
protected $m_sClass;
|
protected $m_sClass;
|
||||||
protected $m_sTargetState;
|
protected $m_sTargetState;
|
||||||
protected $m_aWizardSteps;
|
protected $m_aWizardSteps;
|
||||||
|
|
||||||
public function __construct($oPage, $sClass, $sTargetState = '')
|
public function __construct($oPage, $sClass, $sTargetState = '')
|
||||||
{
|
{
|
||||||
$this->m_oPage = $oPage;
|
$this->m_oPage = $oPage;
|
||||||
$this->m_sClass = $sClass;
|
$this->m_sClass = $sClass;
|
||||||
if (empty($sTargetState))
|
if (empty($sTargetState)) {
|
||||||
{
|
|
||||||
$sTargetState = MetaModel::GetDefaultState($sClass);
|
$sTargetState = MetaModel::GetDefaultState($sClass);
|
||||||
}
|
}
|
||||||
$this->m_sTargetState = $sTargetState;
|
$this->m_sTargetState = $sTargetState;
|
||||||
$this->m_aWizardSteps = $this->ComputeWizardStructure();
|
$this->m_aWizardSteps = $this->ComputeWizardStructure();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetObjectClass() { return $this->m_sClass; }
|
public function GetObjectClass()
|
||||||
public function GetTargetState() { return $this->m_sTargetState; }
|
{
|
||||||
public function GetWizardStructure() { return $this->m_aWizardSteps; }
|
return $this->m_sClass;
|
||||||
|
}
|
||||||
|
public function GetTargetState()
|
||||||
|
{
|
||||||
|
return $this->m_sTargetState;
|
||||||
|
}
|
||||||
|
public function GetWizardStructure()
|
||||||
|
{
|
||||||
|
return $this->m_aWizardSteps;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays one step of the wizard
|
* Displays one step of the wizard
|
||||||
*/
|
*/
|
||||||
public function DisplayWizardStep($aStep, $iStepIndex, &$iMaxInputId, &$aFieldsMap, $bFinishEnabled = false, $aArgs = array())
|
public function DisplayWizardStep($aStep, $iStepIndex, &$iMaxInputId, &$aFieldsMap, $bFinishEnabled = false, $aArgs = [])
|
||||||
{
|
{
|
||||||
if ($iStepIndex == 1) // one big form that contains everything, to make sure that the uploaded files are posted too
|
if ($iStepIndex == 1) { // one big form that contains everything, to make sure that the uploaded files are posted too
|
||||||
{
|
|
||||||
$this->m_oPage->add("<form method=\"post\" enctype=\"multipart/form-data\" action=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php\">\n");
|
$this->m_oPage->add("<form method=\"post\" enctype=\"multipart/form-data\" action=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php\">\n");
|
||||||
}
|
}
|
||||||
$this->m_oPage->add("<div class=\"wizContainer\" id=\"wizStep$iStepIndex\" style=\"display:none;\">\n");
|
$this->m_oPage->add("<div class=\"wizContainer\" id=\"wizStep$iStepIndex\" style=\"display:none;\">\n");
|
||||||
$this->m_oPage->add("<a name=\"step$iStepIndex\" />\n");
|
$this->m_oPage->add("<a name=\"step$iStepIndex\" />\n");
|
||||||
$aStates = MetaModel::EnumStates($this->m_sClass);
|
$aStates = MetaModel::EnumStates($this->m_sClass);
|
||||||
$aDetails = array();
|
$aDetails = [];
|
||||||
$sJSHandlerCode = ''; // Javascript code to be executed each time this step of the wizard is entered
|
$sJSHandlerCode = ''; // Javascript code to be executed each time this step of the wizard is entered
|
||||||
foreach($aStep as $sAttCode)
|
foreach ($aStep as $sAttCode) {
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||||
if ($oAttDef->IsWritable())
|
if ($oAttDef->IsWritable()) {
|
||||||
{
|
|
||||||
$sAttLabel = $oAttDef->GetLabel();
|
$sAttLabel = $oAttDef->GetLabel();
|
||||||
$iOptions = isset($aStates[$this->m_sTargetState]['attribute_list'][$sAttCode]) ? $aStates[$this->m_sTargetState]['attribute_list'][$sAttCode] : 0;
|
$iOptions = isset($aStates[$this->m_sTargetState]['attribute_list'][$sAttCode]) ? $aStates[$this->m_sTargetState]['attribute_list'][$sAttCode] : 0;
|
||||||
|
|
||||||
$aPrerequisites = $oAttDef->GetPrerequisiteAttributes();
|
$aPrerequisites = $oAttDef->GetPrerequisiteAttributes();
|
||||||
if ($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT))
|
if ($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) {
|
||||||
{
|
$aFields[$sAttCode] = [];
|
||||||
$aFields[$sAttCode] = array();
|
foreach ($aPrerequisites as $sCode) {
|
||||||
foreach($aPrerequisites as $sCode)
|
|
||||||
{
|
|
||||||
$aFields[$sAttCode][$sCode] = '';
|
$aFields[$sAttCode][$sCode] = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count($aPrerequisites) > 0)
|
if (count($aPrerequisites) > 0) {
|
||||||
{
|
|
||||||
$aOptions[] = 'Prerequisites: '.implode(', ', $aPrerequisites);
|
$aOptions[] = 'Prerequisites: '.implode(', ', $aPrerequisites);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sFieldFlag = (($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE)) || (!$oAttDef->IsNullAllowed()) )? ' <span class="hilite">*</span>' : '';
|
$sFieldFlag = (($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE)) || (!$oAttDef->IsNullAllowed())) ? ' <span class="hilite">*</span>' : '';
|
||||||
$oDefaultValuesSet = $oAttDef->GetDefaultValue(/* $oObject->ToArgs() */); // @@@ TO DO: get the object's current value if the object exists
|
$oDefaultValuesSet = $oAttDef->GetDefaultValue(/* $oObject->ToArgs() */); // @@@ TO DO: get the object's current value if the object exists
|
||||||
$sHTMLValue = cmdbAbstractObject::GetFormElementForField($this->m_oPage, $this->m_sClass, $sAttCode, $oAttDef, $oDefaultValuesSet, '', "att_$iMaxInputId", '', $iOptions, $aArgs);
|
$sHTMLValue = cmdbAbstractObject::GetFormElementForField($this->m_oPage, $this->m_sClass, $sAttCode, $oAttDef, $oDefaultValuesSet, '', "att_$iMaxInputId", '', $iOptions, $aArgs);
|
||||||
$aFieldsMap["att_$iMaxInputId"] = $sAttCode;
|
$aFieldsMap["att_$iMaxInputId"] = $sAttCode;
|
||||||
$aDetails[] = array('label' => '<span title="'.$oAttDef->GetDescription().'">'.$oAttDef->GetLabel().$sFieldFlag.'</span>', 'value' => "<span id=\"field_att_$iMaxInputId\">$sHTMLValue</span>");
|
$aDetails[] = ['label' => '<span title="'.$oAttDef->GetDescription().'">'.$oAttDef->GetLabel().$sFieldFlag.'</span>', 'value' => "<span id=\"field_att_$iMaxInputId\">$sHTMLValue</span>"];
|
||||||
if ($oAttDef->GetValuesDef() != null)
|
if ($oAttDef->GetValuesDef() != null) {
|
||||||
{
|
|
||||||
$sJSHandlerCode .= "\toWizardHelper.RequestAllowedValues('$sAttCode');\n";
|
$sJSHandlerCode .= "\toWizardHelper.RequestAllowedValues('$sAttCode');\n";
|
||||||
}
|
}
|
||||||
if ($oAttDef->GetDefaultValue() != null)
|
if ($oAttDef->GetDefaultValue() != null) {
|
||||||
{
|
|
||||||
$sJSHandlerCode .= "\toWizardHelper.RequestDefaultValue('$sAttCode');\n";
|
$sJSHandlerCode .= "\toWizardHelper.RequestDefaultValue('$sAttCode');\n";
|
||||||
}
|
}
|
||||||
if ($oAttDef->IsLinkSet())
|
if ($oAttDef->IsLinkSet()) {
|
||||||
{
|
|
||||||
$sJSHandlerCode .= "\toLinkWidgetatt_$iMaxInputId.Init();";
|
$sJSHandlerCode .= "\toLinkWidgetatt_$iMaxInputId.Init();";
|
||||||
}
|
}
|
||||||
$iMaxInputId++;
|
$iMaxInputId++;
|
||||||
@@ -126,11 +125,11 @@ $sJSHandlerCode
|
|||||||
}
|
}
|
||||||
");
|
");
|
||||||
$this->m_oPage->add("</div>\n\n");
|
$this->m_oPage->add("</div>\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the final step of the wizard: a confirmation screen
|
* Display the final step of the wizard: a confirmation screen
|
||||||
*/
|
*/
|
||||||
public function DisplayFinalStep($iStepIndex, $aFieldsMap)
|
public function DisplayFinalStep($iStepIndex, $aFieldsMap)
|
||||||
{
|
{
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
@@ -141,136 +140,116 @@ $sJSHandlerCode
|
|||||||
$this->m_oPage->add("<input type=\"hidden\" name=\"transaction_id\" value=\"".utils::GetNewTransactionId()."\" />\n");
|
$this->m_oPage->add("<input type=\"hidden\" name=\"transaction_id\" value=\"".utils::GetNewTransactionId()."\" />\n");
|
||||||
$this->m_oPage->add("<input type=\"hidden\" id=\"wizard_json_obj\" name=\"json_obj\" value=\"\" />\n");
|
$this->m_oPage->add("<input type=\"hidden\" id=\"wizard_json_obj\" name=\"json_obj\" value=\"\" />\n");
|
||||||
$sScript = "function OnEnterStep$iStepIndex() {\n";
|
$sScript = "function OnEnterStep$iStepIndex() {\n";
|
||||||
foreach($aFieldsMap as $iInputId => $sAttCode)
|
foreach ($aFieldsMap as $iInputId => $sAttCode) {
|
||||||
{
|
$sScript .= "\toWizardHelper.UpdateCurrentValue('$sAttCode');\n";
|
||||||
$sScript .= "\toWizardHelper.UpdateCurrentValue('$sAttCode');\n";
|
|
||||||
}
|
}
|
||||||
$sScript .= "\toWizardHelper.Preview('object_preview');\n";
|
$sScript .= "\toWizardHelper.Preview('object_preview');\n";
|
||||||
$sScript .= "\t$('#wizard_json_obj').val(oWizardHelper.ToJSON());\n";
|
$sScript .= "\t$('#wizard_json_obj').val(oWizardHelper.ToJSON());\n";
|
||||||
$sScript .= "}\n";
|
$sScript .= "}\n";
|
||||||
$this->m_oPage->add_script($sScript);
|
$this->m_oPage->add_script($sScript);
|
||||||
$this->m_oPage->add("<div id=\"object_preview\">\n");
|
$this->m_oPage->add("<div id=\"object_preview\">\n");
|
||||||
$this->m_oPage->add("</div>\n");
|
$this->m_oPage->add("</div>\n");
|
||||||
$this->m_oPage->add($oAppContext->GetForForm());
|
$this->m_oPage->add($oAppContext->GetForForm());
|
||||||
$this->m_oPage->add("<input type=\"button\" value=\"".Dict::S('UI:Button:Back')."\" onClick=\"GoToStep($iStepIndex, $iStepIndex - 1)\" />");
|
$this->m_oPage->add("<input type=\"button\" value=\"".Dict::S('UI:Button:Back')."\" onClick=\"GoToStep($iStepIndex, $iStepIndex - 1)\" />");
|
||||||
$this->m_oPage->add("<input type=\"submit\" value=\"Create ".MetaModel::GetName($this->m_sClass)."\" />\n");
|
$this->m_oPage->add("<input type=\"submit\" value=\"Create ".MetaModel::GetName($this->m_sClass)."\" />\n");
|
||||||
$this->m_oPage->add("</div>\n");
|
$this->m_oPage->add("</div>\n");
|
||||||
$this->m_oPage->add("</form>\n");
|
$this->m_oPage->add("</form>\n");
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Compute the order of the fields & pages in the wizard
|
* Compute the order of the fields & pages in the wizard
|
||||||
* @param $oPage iTopWebPage The current page (used to display error messages)
|
* @param $oPage iTopWebPage The current page (used to display error messages)
|
||||||
* @param $sClass string Name of the class
|
* @param $sClass string Name of the class
|
||||||
* @param $sStateCode string Code of the target state of the object
|
* @param $sStateCode string Code of the target state of the object
|
||||||
* @return hash Two dimensional array: each element represents the list of fields for a given page
|
* @return hash Two dimensional array: each element represents the list of fields for a given page
|
||||||
*/
|
*/
|
||||||
protected function ComputeWizardStructure()
|
protected function ComputeWizardStructure()
|
||||||
{
|
{
|
||||||
$aWizardSteps = array( 'mandatory' => array(), 'optional' => array());
|
$aWizardSteps = [ 'mandatory' => [], 'optional' => []];
|
||||||
$aFieldsDone = array(); // Store all the fields that are already covered by a previous step of the wizard
|
$aFieldsDone = []; // Store all the fields that are already covered by a previous step of the wizard
|
||||||
|
|
||||||
$aStates = MetaModel::EnumStates($this->m_sClass);
|
$aStates = MetaModel::EnumStates($this->m_sClass);
|
||||||
$sStateAttCode = MetaModel::GetStateAttributeCode($this->m_sClass);
|
$sStateAttCode = MetaModel::GetStateAttributeCode($this->m_sClass);
|
||||||
|
|
||||||
$aMandatoryAttributes = array();
|
|
||||||
// Some attributes are always mandatory independently of the state machine (if any)
|
|
||||||
foreach(MetaModel::GetAttributesList($this->m_sClass) as $sAttCode)
|
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
|
||||||
if (!$oAttDef->IsExternalField() && !$oAttDef->IsNullAllowed() &&
|
|
||||||
$oAttDef->IsWritable() && ($sAttCode != $sStateAttCode) )
|
|
||||||
{
|
|
||||||
$aMandatoryAttributes[$sAttCode] = OPT_ATT_MANDATORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now check the attributes that are mandatory in the specified state
|
$aMandatoryAttributes = [];
|
||||||
if ( (!empty($this->m_sTargetState)) && (count($aStates[$this->m_sTargetState]['attribute_list']) > 0) )
|
// Some attributes are always mandatory independently of the state machine (if any)
|
||||||
{
|
foreach (MetaModel::GetAttributesList($this->m_sClass) as $sAttCode) {
|
||||||
|
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||||
|
if (!$oAttDef->IsExternalField() && !$oAttDef->IsNullAllowed() &&
|
||||||
|
$oAttDef->IsWritable() && ($sAttCode != $sStateAttCode)) {
|
||||||
|
$aMandatoryAttributes[$sAttCode] = OPT_ATT_MANDATORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now check the attributes that are mandatory in the specified state
|
||||||
|
if ((!empty($this->m_sTargetState)) && (count($aStates[$this->m_sTargetState]['attribute_list']) > 0)) {
|
||||||
// Check all the fields that *must* be included in the wizard for this
|
// Check all the fields that *must* be included in the wizard for this
|
||||||
// particular target state
|
// particular target state
|
||||||
$aFields = array();
|
$aFields = [];
|
||||||
foreach($aStates[$this->m_sTargetState]['attribute_list'] as $sAttCode => $iOptions)
|
foreach ($aStates[$this->m_sTargetState]['attribute_list'] as $sAttCode => $iOptions) {
|
||||||
{
|
if ((isset($aMandatoryAttributes[$sAttCode])) &&
|
||||||
if ( (isset($aMandatoryAttributes[$sAttCode])) &&
|
($aMandatoryAttributes[$sAttCode] & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT))) {
|
||||||
($aMandatoryAttributes[$sAttCode] & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) )
|
|
||||||
{
|
|
||||||
$aMandatoryAttributes[$sAttCode] |= $iOptions;
|
$aMandatoryAttributes[$sAttCode] |= $iOptions;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aMandatoryAttributes[$sAttCode] = $iOptions;
|
$aMandatoryAttributes[$sAttCode] = $iOptions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check all the fields that *must* be included in the wizard
|
// Check all the fields that *must* be included in the wizard
|
||||||
// i.e. all mandatory, must-change or must-prompt fields that are
|
// i.e. all mandatory, must-change or must-prompt fields that are
|
||||||
// not also read-only or hidden.
|
// not also read-only or hidden.
|
||||||
// Some fields may be required (null not allowed) from the database
|
// Some fields may be required (null not allowed) from the database
|
||||||
// perspective, but hidden or read-only from the user interface perspective
|
// perspective, but hidden or read-only from the user interface perspective
|
||||||
$aFields = array();
|
$aFields = [];
|
||||||
foreach($aMandatoryAttributes as $sAttCode => $iOptions)
|
foreach ($aMandatoryAttributes as $sAttCode => $iOptions) {
|
||||||
{
|
if (($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) &&
|
||||||
if ( ($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) &&
|
!($iOptions & (OPT_ATT_READONLY | OPT_ATT_HIDDEN))) {
|
||||||
!($iOptions & (OPT_ATT_READONLY | OPT_ATT_HIDDEN)) )
|
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||||
$aPrerequisites = $oAttDef->GetPrerequisiteAttributes();
|
$aPrerequisites = $oAttDef->GetPrerequisiteAttributes();
|
||||||
$aFields[$sAttCode] = array();
|
$aFields[$sAttCode] = [];
|
||||||
foreach($aPrerequisites as $sCode)
|
foreach ($aPrerequisites as $sCode) {
|
||||||
{
|
|
||||||
$aFields[$sAttCode][$sCode] = '';
|
$aFields[$sAttCode][$sCode] = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now use the dependencies between the fields to order them
|
// Now use the dependencies between the fields to order them
|
||||||
// Start from the order of the 'details'
|
// Start from the order of the 'details'
|
||||||
$aList = MetaModel::FlattenZlist(MetaModel::GetZListItems($this->m_sClass, 'details'));
|
$aList = MetaModel::FlattenZlist(MetaModel::GetZListItems($this->m_sClass, 'details'));
|
||||||
$index = 0;
|
$index = 0;
|
||||||
$aOrder = array();
|
$aOrder = [];
|
||||||
foreach($aFields as $sAttCode => $void)
|
foreach ($aFields as $sAttCode => $void) {
|
||||||
{
|
$aOrder[$sAttCode] = 999; // At the end of the list...
|
||||||
$aOrder[$sAttCode] = 999; // At the end of the list...
|
|
||||||
}
|
}
|
||||||
foreach($aList as $sAttCode)
|
foreach ($aList as $sAttCode) {
|
||||||
{
|
if (array_key_exists($sAttCode, $aFields)) {
|
||||||
if (array_key_exists($sAttCode, $aFields))
|
|
||||||
{
|
|
||||||
$aOrder[$sAttCode] = $index;
|
$aOrder[$sAttCode] = $index;
|
||||||
}
|
}
|
||||||
$index++;
|
$index++;
|
||||||
}
|
}
|
||||||
foreach($aFields as $sAttCode => $aDependencies)
|
foreach ($aFields as $sAttCode => $aDependencies) {
|
||||||
{
|
|
||||||
// All fields with no remaining dependencies can be entered at this
|
// All fields with no remaining dependencies can be entered at this
|
||||||
// step of the wizard
|
// step of the wizard
|
||||||
if (count($aDependencies) > 0)
|
if (count($aDependencies) > 0) {
|
||||||
{
|
|
||||||
$iMaxPos = 0;
|
$iMaxPos = 0;
|
||||||
// Remove this field from the dependencies of the other fields
|
// Remove this field from the dependencies of the other fields
|
||||||
foreach($aDependencies as $sDependentAttCode => $void)
|
foreach ($aDependencies as $sDependentAttCode => $void) {
|
||||||
{
|
|
||||||
// position the current field after the ones it depends on
|
// position the current field after the ones it depends on
|
||||||
$iMaxPos = max($iMaxPos, 1+$aOrder[$sDependentAttCode]);
|
$iMaxPos = max($iMaxPos, 1 + $aOrder[$sDependentAttCode]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
asort($aOrder);
|
asort($aOrder);
|
||||||
$aCurrentStep = array();
|
$aCurrentStep = [];
|
||||||
foreach($aOrder as $sAttCode => $rank)
|
foreach ($aOrder as $sAttCode => $rank) {
|
||||||
{
|
|
||||||
$aCurrentStep[] = $sAttCode;
|
$aCurrentStep[] = $sAttCode;
|
||||||
$aFieldsDone[$sAttCode] = '';
|
$aFieldsDone[$sAttCode] = '';
|
||||||
}
|
}
|
||||||
$aWizardSteps['mandatory'][] = $aCurrentStep;
|
$aWizardSteps['mandatory'][] = $aCurrentStep;
|
||||||
|
|
||||||
|
|
||||||
// Now computes the steps to fill the optional fields
|
// Now computes the steps to fill the optional fields
|
||||||
$aFields = array(); // reset
|
$aFields = []; // reset
|
||||||
foreach(MetaModel::ListAttributeDefs($this->m_sClass) as $sAttCode=>$oAttDef)
|
foreach (MetaModel::ListAttributeDefs($this->m_sClass) as $sAttCode => $oAttDef) {
|
||||||
{
|
|
||||||
$iOptions = (isset($aStates[$this->m_sTargetState]['attribute_list'][$sAttCode])) ? $aStates[$this->m_sTargetState]['attribute_list'][$sAttCode] : 0;
|
$iOptions = (isset($aStates[$this->m_sTargetState]['attribute_list'][$sAttCode])) ? $aStates[$this->m_sTargetState]['attribute_list'][$sAttCode] : 0;
|
||||||
if (($sStateAttCode != $sAttCode) &&
|
if (($sStateAttCode != $sAttCode) &&
|
||||||
(!$oAttDef->IsExternalField()) &&
|
(!$oAttDef->IsExternalField()) &&
|
||||||
@@ -282,7 +261,7 @@ $sJSHandlerCode
|
|||||||
// are removed from the 'optional' part of the wizard
|
// are removed from the 'optional' part of the wizard
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||||
$aPrerequisites = $oAttDef->GetPrerequisiteAttributes();
|
$aPrerequisites = $oAttDef->GetPrerequisiteAttributes();
|
||||||
$aFields[$sAttCode] = array();
|
$aFields[$sAttCode] = [];
|
||||||
foreach ($aPrerequisites as $sCode) {
|
foreach ($aPrerequisites as $sCode) {
|
||||||
if (!isset($aFieldsDone[$sCode])) {
|
if (!isset($aFieldsDone[$sCode])) {
|
||||||
// retain only the dependencies that were not covered
|
// retain only the dependencies that were not covered
|
||||||
@@ -293,28 +272,23 @@ $sJSHandlerCode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Now use the dependencies between the fields to order them
|
// Now use the dependencies between the fields to order them
|
||||||
while(count($aFields) > 0)
|
while (count($aFields) > 0) {
|
||||||
{
|
$aCurrentStep = [];
|
||||||
$aCurrentStep = array();
|
foreach ($aFields as $sAttCode => $aDependencies) {
|
||||||
foreach($aFields as $sAttCode => $aDependencies)
|
|
||||||
{
|
|
||||||
// All fields with no remaining dependencies can be entered at this
|
// All fields with no remaining dependencies can be entered at this
|
||||||
// step of the wizard
|
// step of the wizard
|
||||||
if (count($aDependencies) == 0)
|
if (count($aDependencies) == 0) {
|
||||||
{
|
|
||||||
$aCurrentStep[] = $sAttCode;
|
$aCurrentStep[] = $sAttCode;
|
||||||
$aFieldsDone[$sAttCode] = '';
|
$aFieldsDone[$sAttCode] = '';
|
||||||
unset($aFields[$sAttCode]);
|
unset($aFields[$sAttCode]);
|
||||||
// Remove this field from the dependencies of the other fields
|
// Remove this field from the dependencies of the other fields
|
||||||
foreach($aFields as $sUpdatedCode => $aDummy)
|
foreach ($aFields as $sUpdatedCode => $aDummy) {
|
||||||
{
|
|
||||||
// remove the dependency
|
// remove the dependency
|
||||||
unset($aFields[$sUpdatedCode][$sAttCode]);
|
unset($aFields[$sUpdatedCode][$sAttCode]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count($aCurrentStep) == 0)
|
if (count($aCurrentStep) == 0) {
|
||||||
{
|
|
||||||
// This step of the wizard would contain NO field !
|
// This step of the wizard would contain NO field !
|
||||||
$this->m_oPage->add(Dict::S('UI:Error:WizardCircularReferenceInDependencies'));
|
$this->m_oPage->add(Dict::S('UI:Error:WizardCircularReferenceInDependencies'));
|
||||||
print_r($aFields);
|
print_r($aFields);
|
||||||
@@ -323,7 +297,6 @@ $sJSHandlerCode
|
|||||||
$aWizardSteps['optional'][] = $aCurrentStep;
|
$aWizardSteps['optional'][] = $aCurrentStep;
|
||||||
}
|
}
|
||||||
return $aWizardSteps;
|
return $aWizardSteps;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// 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
|
// 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
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -31,40 +32,39 @@ class UserDashboard extends DBObject
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "gui",
|
"category" => "gui",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => array('user_id', 'menu_code'),
|
"name_attcode" => ['user_id', 'menu_code'],
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array(),
|
"reconc_keys" => [],
|
||||||
"db_table" => "priv_app_dashboards",
|
"db_table" => "priv_app_dashboards",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
);
|
];
|
||||||
|
|
||||||
MetaModel::Init_Params($aParams);
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("user_id", array("targetclass"=>"User", "allowed_values"=>null, "sql"=>"user_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("menu_code", array("allowed_values"=>null, "sql"=>"menu_code", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeText("contents", array("allowed_values"=>null, "sql"=>"contents", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
|
||||||
|
|
||||||
MetaModel::Init_SetZListItems('default_search', array (
|
MetaModel::Init_Params($aParams);
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("user_id", ["targetclass" => "User", "allowed_values" => null, "sql" => "user_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeString("menu_code", ["allowed_values" => null, "sql" => "menu_code", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
|
MetaModel::Init_AddAttribute(new AttributeText("contents", ["allowed_values" => null, "sql" => "contents", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
||||||
|
|
||||||
|
MetaModel::Init_SetZListItems('default_search', [
|
||||||
0 => 'user_id',
|
0 => 'user_id',
|
||||||
1 => 'menu_code',
|
1 => 'menu_code',
|
||||||
));
|
]);
|
||||||
MetaModel::Init_SetZListItems('list', array (
|
MetaModel::Init_SetZListItems('list', [
|
||||||
0 => 'user_id',
|
0 => 'user_id',
|
||||||
1 => 'menu_code',
|
1 => 'menu_code',
|
||||||
));
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overloading this function here to secure a fix done right before the release
|
* Overloading this function here to secure a fix done right before the release
|
||||||
* The real fix should be to implement this verb in DBObject
|
* The real fix should be to implement this verb in DBObject
|
||||||
*/
|
*/
|
||||||
public function DBDeleteTracked(CMDBChange $oChange, $bSkipStrongSecurity = null, &$oDeletionPlan = null)
|
public function DBDeleteTracked(CMDBChange $oChange, $bSkipStrongSecurity = null, &$oDeletionPlan = null)
|
||||||
{
|
{
|
||||||
$this->DBDelete($oDeletionPlan);
|
$this->DBDelete($oDeletionPlan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// 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
|
// 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
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -227,13 +228,12 @@ class appUserPreferences extends DBObject
|
|||||||
// No prefs (yet) for this user, create the object
|
// No prefs (yet) for this user, create the object
|
||||||
$oObj = new appUserPreferences();
|
$oObj = new appUserPreferences();
|
||||||
$oObj->Set('userid', $sUserId);
|
$oObj->Set('userid', $sUserId);
|
||||||
$oObj->Set('preferences', array()); // Default preferences: an empty array
|
$oObj->Set('preferences', []); // Default preferences: an empty array
|
||||||
try {
|
try {
|
||||||
utils::PushArchiveMode(false);
|
utils::PushArchiveMode(false);
|
||||||
$oObj->DBInsert();
|
$oObj->DBInsert();
|
||||||
utils::PopArchiveMode();
|
utils::PopArchiveMode();
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (Exception $e) {
|
|
||||||
// Ignore errors
|
// Ignore errors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -245,25 +245,25 @@ class appUserPreferences extends DBObject
|
|||||||
*/
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams = array
|
$aParams =
|
||||||
(
|
[
|
||||||
"category" => "gui",
|
"category" => "gui",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "login",
|
"name_attcode" => "login",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => array("userid","login"),
|
"reconc_keys" => ["userid","login"],
|
||||||
"db_table" => "priv_app_preferences",
|
"db_table" => "priv_app_preferences",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
);
|
];
|
||||||
|
|
||||||
MetaModel::Init_Params($aParams);
|
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 AttributeExternalKey("userid", ["targetclass" => "User", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
||||||
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 AttributePropertySet("preferences", ["allowed_values" => null, "sql" => "preferences", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("org_id", array("allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "org_id")));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("org_id", ["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_AddAttribute(new AttributeExternalField("login", ["allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login"]));
|
||||||
MetaModel::Init_SetZListItems('list', array('org_id','preferences'));
|
MetaModel::Init_SetZListItems('list', ['org_id','preferences']);
|
||||||
MetaModel::Init_SetZListItems('default_search', array('userid','login','org_id'));
|
MetaModel::Init_SetZListItems('default_search', ['userid','login','org_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/WebPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/WebPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/WebPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/WebPage.php, now loadable using autoloader');
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// 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
|
// 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
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class WizardHelper
|
* Class WizardHelper
|
||||||
*
|
*
|
||||||
@@ -31,7 +31,7 @@ require_once(APPROOT.'/application/uiwizard.class.inc.php');
|
|||||||
class WizardHelper
|
class WizardHelper
|
||||||
{
|
{
|
||||||
protected $m_aData;
|
protected $m_aData;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -39,26 +39,20 @@ class WizardHelper
|
|||||||
* Constructs the PHP target object from the parameters sent to the web page by the wizard
|
* Constructs the PHP target object from the parameters sent to the web page by the wizard
|
||||||
* @param boolean $bReadUploadedFiles True to also read any uploaded file (for blob/document fields)
|
* @param boolean $bReadUploadedFiles True to also read any uploaded file (for blob/document fields)
|
||||||
* @return object
|
* @return object
|
||||||
*/
|
*/
|
||||||
public function GetTargetObject($bReadUploadedFiles = false)
|
public function GetTargetObject($bReadUploadedFiles = false)
|
||||||
{
|
{
|
||||||
if (isset($this->m_aData['m_oCurrentValues']['id']))
|
if (isset($this->m_aData['m_oCurrentValues']['id'])) {
|
||||||
{
|
|
||||||
$oObj = MetaModel::GetObject($this->m_aData['m_sClass'], $this->m_aData['m_oCurrentValues']['id']);
|
$oObj = MetaModel::GetObject($this->m_aData['m_sClass'], $this->m_aData['m_oCurrentValues']['id']);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oObj = MetaModel::NewObject($this->m_aData['m_sClass']);
|
$oObj = MetaModel::NewObject($this->m_aData['m_sClass']);
|
||||||
}
|
}
|
||||||
foreach($this->m_aData['m_oCurrentValues'] as $sAttCode => $value)
|
foreach ($this->m_aData['m_oCurrentValues'] as $sAttCode => $value) {
|
||||||
{
|
|
||||||
// Because this is stored in a Javascript array, unused indexes
|
// Because this is stored in a Javascript array, unused indexes
|
||||||
// are filled with null values and unused keys (stored as strings) contain $$NULL$$
|
// are filled with null values and unused keys (stored as strings) contain $$NULL$$
|
||||||
if ( ($sAttCode !='id') && ($value !== '$$NULL$$'))
|
if (($sAttCode != 'id') && ($value !== '$$NULL$$')) {
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->m_aData['m_sClass'], $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($this->m_aData['m_sClass'], $sAttCode);
|
||||||
if (($oAttDef->IsLinkSet()) && ($value != '') )
|
if (($oAttDef->IsLinkSet()) && ($value != '')) {
|
||||||
{
|
|
||||||
// special handling for lists
|
// special handling for lists
|
||||||
// assumes this is handled as an array of objects
|
// assumes this is handled as an array of objects
|
||||||
// thus encoded in json like: [ { name:'link1', 'id': 123}, { name:'link2', 'id': 124}...]
|
// thus encoded in json like: [ { name:'link1', 'id': 123}, { name:'link2', 'id': 124}...]
|
||||||
@@ -71,47 +65,35 @@ class WizardHelper
|
|||||||
// Check what are the meaningful attributes
|
// Check what are the meaningful attributes
|
||||||
$aFields = $this->GetLinkedWizardStructure($oAttDef);
|
$aFields = $this->GetLinkedWizardStructure($oAttDef);
|
||||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||||
$aLinkedObjectsArray = array();
|
$aLinkedObjectsArray = [];
|
||||||
if (!is_array($aData)) {
|
if (!is_array($aData)) {
|
||||||
echo("aData: '$aData' (value: '$value')\n");
|
echo("aData: '$aData' (value: '$value')\n");
|
||||||
}
|
}
|
||||||
foreach ($aData as $aLinkedObject)
|
foreach ($aData as $aLinkedObject) {
|
||||||
{
|
|
||||||
$oLinkedObj = MetaModel::NewObject($sLinkedClass);
|
$oLinkedObj = MetaModel::NewObject($sLinkedClass);
|
||||||
foreach($aFields as $sLinkedAttCode)
|
foreach ($aFields as $sLinkedAttCode) {
|
||||||
{
|
if (isset($aLinkedObject[$sLinkedAttCode]) && ($aLinkedObject[$sLinkedAttCode] !== null)) {
|
||||||
if ( isset($aLinkedObject[$sLinkedAttCode]) && ($aLinkedObject[$sLinkedAttCode] !== null) )
|
|
||||||
{
|
|
||||||
$sLinkedAttDef = MetaModel::GetAttributeDef($sLinkedClass, $sLinkedAttCode);
|
$sLinkedAttDef = MetaModel::GetAttributeDef($sLinkedClass, $sLinkedAttCode);
|
||||||
if (($sLinkedAttDef->IsExternalKey()) && ($aLinkedObject[$sLinkedAttCode] != '') && ($aLinkedObject[$sLinkedAttCode] > 0) )
|
if (($sLinkedAttDef->IsExternalKey()) && ($aLinkedObject[$sLinkedAttCode] != '') && ($aLinkedObject[$sLinkedAttCode] > 0)) {
|
||||||
{
|
|
||||||
// For external keys: load the target object so that external fields
|
// For external keys: load the target object so that external fields
|
||||||
// get filled too
|
// get filled too
|
||||||
$oTargetObj = MetaModel::GetObject($sLinkedAttDef->GetTargetClass(), $aLinkedObject[$sLinkedAttCode]);
|
$oTargetObj = MetaModel::GetObject($sLinkedAttDef->GetTargetClass(), $aLinkedObject[$sLinkedAttCode]);
|
||||||
$oLinkedObj->Set($sLinkedAttCode, $oTargetObj);
|
$oLinkedObj->Set($sLinkedAttCode, $oTargetObj);
|
||||||
}
|
} elseif ($sLinkedAttDef instanceof AttributeDateTime) {
|
||||||
elseif($sLinkedAttDef instanceof AttributeDateTime)
|
$sDateClass = get_class($sLinkedAttDef);
|
||||||
{
|
$sDate = $aLinkedObject[$sLinkedAttCode];
|
||||||
$sDateClass = get_class($sLinkedAttDef);
|
if ($sDate !== null && $sDate !== '') {
|
||||||
$sDate = $aLinkedObject[$sLinkedAttCode];
|
$oDateTimeFormat = $sDateClass::GetFormat();
|
||||||
if($sDate !== null && $sDate !== '')
|
$oDate = $oDateTimeFormat->Parse($sDate);
|
||||||
{
|
if ($sDateClass == "AttributeDate") {
|
||||||
$oDateTimeFormat = $sDateClass::GetFormat();
|
$sDate = $oDate->format('Y-m-d');
|
||||||
$oDate = $oDateTimeFormat->Parse($sDate);
|
} else {
|
||||||
if ($sDateClass == "AttributeDate")
|
$sDate = $oDate->format('Y-m-d H:i:s');
|
||||||
{
|
}
|
||||||
$sDate = $oDate->format('Y-m-d');
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$sDate = $oDate->format('Y-m-d H:i:s');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$oLinkedObj->Set($sLinkedAttCode, $sDate);
|
$oLinkedObj->Set($sLinkedAttCode, $sDate);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oLinkedObj->Set($sLinkedAttCode, $aLinkedObject[$sLinkedAttCode]);
|
$oLinkedObj->Set($sLinkedAttCode, $aLinkedObject[$sLinkedAttCode]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,189 +102,147 @@ class WizardHelper
|
|||||||
}
|
}
|
||||||
$oSet = DBObjectSet::FromArray($sLinkedClass, $aLinkedObjectsArray);
|
$oSet = DBObjectSet::FromArray($sLinkedClass, $aLinkedObjectsArray);
|
||||||
$oObj->Set($sAttCode, $oSet);
|
$oObj->Set($sAttCode, $oSet);
|
||||||
}
|
} elseif ($oAttDef->GetEditClass() == 'Document') {
|
||||||
else if ( $oAttDef->GetEditClass() == 'Document' )
|
if ($bReadUploadedFiles) {
|
||||||
{
|
|
||||||
if ($bReadUploadedFiles)
|
|
||||||
{
|
|
||||||
$oDocument = utils::ReadPostedDocument('attr_'.$sAttCode, 'fcontents');
|
$oDocument = utils::ReadPostedDocument('attr_'.$sAttCode, 'fcontents');
|
||||||
$oObj->Set($sAttCode, $oDocument);
|
$oObj->Set($sAttCode, $oDocument);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Create a new empty document, just for displaying the file name
|
// Create a new empty document, just for displaying the file name
|
||||||
$oDocument = new ormDocument(null, '', $value);
|
$oDocument = new ormDocument(null, '', $value);
|
||||||
$oObj->Set($sAttCode, $oDocument);
|
$oObj->Set($sAttCode, $oDocument);
|
||||||
}
|
}
|
||||||
}
|
} elseif ($oAttDef->GetEditClass() == 'Image') {
|
||||||
else if ( $oAttDef->GetEditClass() == 'Image' )
|
if ($bReadUploadedFiles) {
|
||||||
{
|
|
||||||
if ($bReadUploadedFiles)
|
|
||||||
{
|
|
||||||
$oDocument = utils::ReadPostedDocument('attr_'.$sAttCode, 'fcontents');
|
$oDocument = utils::ReadPostedDocument('attr_'.$sAttCode, 'fcontents');
|
||||||
$oObj->Set($sAttCode, $oDocument);
|
$oObj->Set($sAttCode, $oDocument);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Create a new empty document, just for displaying the file name
|
// Create a new empty document, just for displaying the file name
|
||||||
$oDocument = new ormDocument(null, '', $value);
|
$oDocument = new ormDocument(null, '', $value);
|
||||||
$oObj->Set($sAttCode, $oDocument);
|
$oObj->Set($sAttCode, $oDocument);
|
||||||
}
|
}
|
||||||
}
|
} elseif (($oAttDef->IsExternalKey()) && (!empty($value)) && ($value > 0)) {
|
||||||
else if (($oAttDef->IsExternalKey()) && (!empty($value)) && ($value > 0) )
|
|
||||||
{
|
|
||||||
// For external keys: load the target object so that external fields
|
// For external keys: load the target object so that external fields
|
||||||
// get filled too
|
// get filled too
|
||||||
$oTargetObj = MetaModel::GetObject($oAttDef->GetTargetClass(), $value, false);
|
$oTargetObj = MetaModel::GetObject($oAttDef->GetTargetClass(), $value, false);
|
||||||
if ($oTargetObj)
|
if ($oTargetObj) {
|
||||||
{
|
|
||||||
$oObj->Set($sAttCode, $oTargetObj);
|
$oObj->Set($sAttCode, $oTargetObj);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// May happen for security reasons (portal, see ticket N°1074)
|
// May happen for security reasons (portal, see ticket N°1074)
|
||||||
$oObj->Set($sAttCode, $value);
|
$oObj->Set($sAttCode, $value);
|
||||||
}
|
}
|
||||||
}
|
} elseif ($oAttDef instanceof AttributeDateTime) { // AttributeDate is derived from AttributeDateTime
|
||||||
else if ($oAttDef instanceof AttributeDateTime) // AttributeDate is derived from AttributeDateTime
|
if ($value != null) {
|
||||||
{
|
|
||||||
if ($value != null)
|
|
||||||
{
|
|
||||||
$oDate = $oAttDef->GetFormat()->Parse($value);
|
$oDate = $oAttDef->GetFormat()->Parse($value);
|
||||||
if ($oDate instanceof DateTime)
|
if ($oDate instanceof DateTime) {
|
||||||
{
|
|
||||||
$value = $oDate->format($oAttDef->GetInternalFormat());
|
$value = $oDate->format($oAttDef->GetInternalFormat());
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$value = null;
|
$value = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$oObj->Set($sAttCode, $value);
|
$oObj->Set($sAttCode, $value);
|
||||||
}
|
} elseif ($oAttDef instanceof AttributeTagSet) { // AttributeDate is derived from AttributeDateTime
|
||||||
else if ($oAttDef instanceof AttributeTagSet) // AttributeDate is derived from AttributeDateTime
|
if (is_null($value)) {
|
||||||
{
|
|
||||||
if (is_null($value))
|
|
||||||
{
|
|
||||||
// happens if field is hidden (see N°1827)
|
// happens if field is hidden (see N°1827)
|
||||||
$value = array();
|
$value = [];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$value = json_decode($value, true);
|
$value = json_decode($value, true);
|
||||||
}
|
}
|
||||||
$oTagSet = new ormTagSet(get_class($oObj), $sAttCode, $oAttDef->GetMaxItems());
|
$oTagSet = new ormTagSet(get_class($oObj), $sAttCode, $oAttDef->GetMaxItems());
|
||||||
$oTagSet->SetValues($value['orig_value']);
|
$oTagSet->SetValues($value['orig_value']);
|
||||||
$oTagSet->ApplyDelta($value);
|
$oTagSet->ApplyDelta($value);
|
||||||
$oObj->Set($sAttCode, $oTagSet);
|
$oObj->Set($sAttCode, $oTagSet);
|
||||||
}
|
} elseif ($oAttDef instanceof AttributeSet) { // AttributeDate is derived from AttributeDateTime
|
||||||
else if ($oAttDef instanceof AttributeSet) // AttributeDate is derived from AttributeDateTime
|
|
||||||
{
|
|
||||||
$value = json_decode($value, true);
|
$value = json_decode($value, true);
|
||||||
$oTagSet = new ormSet(get_class($oObj), $sAttCode, $oAttDef->GetMaxItems());
|
$oTagSet = new ormSet(get_class($oObj), $sAttCode, $oAttDef->GetMaxItems());
|
||||||
$oTagSet->SetValues($value['orig_value']);
|
$oTagSet->SetValues($value['orig_value']);
|
||||||
$oTagSet->ApplyDelta($value);
|
$oTagSet->ApplyDelta($value);
|
||||||
$oObj->Set($sAttCode, $oTagSet);
|
$oObj->Set($sAttCode, $oTagSet);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$oObj->Set($sAttCode, $value);
|
$oObj->Set($sAttCode, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isset($this->m_aData['m_sState']) && !empty($this->m_aData['m_sState']))
|
if (isset($this->m_aData['m_sState']) && !empty($this->m_aData['m_sState'])) {
|
||||||
{
|
|
||||||
$oObj->Set(MetaModel::GetStateAttributeCode($this->m_aData['m_sClass']), $this->m_aData['m_sState']);
|
$oObj->Set(MetaModel::GetStateAttributeCode($this->m_aData['m_sClass']), $this->m_aData['m_sState']);
|
||||||
}
|
}
|
||||||
$oObj->DoComputeValues();
|
$oObj->DoComputeValues();
|
||||||
return $oObj;
|
return $oObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetFieldsForDefaultValue()
|
public function GetFieldsForDefaultValue()
|
||||||
{
|
{
|
||||||
return $this->m_aData['m_aDefaultValueRequested'];
|
return $this->m_aData['m_aDefaultValueRequested'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SetDefaultValue($sAttCode, $value)
|
public function SetDefaultValue($sAttCode, $value)
|
||||||
{
|
{
|
||||||
// Protect against a request for a non existing field
|
// Protect against a request for a non existing field
|
||||||
if (isset($this->m_aData['m_oFieldsMap'][$sAttCode]))
|
if (isset($this->m_aData['m_oFieldsMap'][$sAttCode])) {
|
||||||
{
|
|
||||||
$oAttDef = MetaModel::GetAttributeDef($this->m_aData['m_sClass'], $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($this->m_aData['m_sClass'], $sAttCode);
|
||||||
if ($oAttDef->GetEditClass() == 'List')
|
if ($oAttDef->GetEditClass() == 'List') {
|
||||||
{
|
|
||||||
// special handling for lists
|
// special handling for lists
|
||||||
// this as to be handled as an array of objects
|
// this as to be handled as an array of objects
|
||||||
// thus encoded in json like: [ { name:'link1', 'id': 123}, { name:'link2', 'id': 124}...]
|
// thus encoded in json like: [ { name:'link1', 'id': 123}, { name:'link2', 'id': 124}...]
|
||||||
// NOT YET IMPLEMENTED !!
|
// NOT YET IMPLEMENTED !!
|
||||||
$oSet = $value;
|
$oSet = $value;
|
||||||
$aData = array();
|
$aData = [];
|
||||||
$aFields = $this->GetLinkedWizardStructure($oAttDef);
|
$aFields = $this->GetLinkedWizardStructure($oAttDef);
|
||||||
while($oLinkedObj = $oSet->fetch())
|
while ($oLinkedObj = $oSet->fetch()) {
|
||||||
{
|
foreach ($aFields as $sLinkedAttCode) {
|
||||||
foreach($aFields as $sLinkedAttCode)
|
|
||||||
{
|
|
||||||
$aRow[$sAttCode] = $oLinkedObj->Get($sLinkedAttCode);
|
$aRow[$sAttCode] = $oLinkedObj->Get($sLinkedAttCode);
|
||||||
}
|
}
|
||||||
$aData[] = $aRow;
|
$aData[] = $aRow;
|
||||||
}
|
}
|
||||||
$this->m_aData['m_oDefaultValue'][$sAttCode] = json_encode($aData);
|
$this->m_aData['m_oDefaultValue'][$sAttCode] = json_encode($aData);
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Normal handling for all other scalar attributes
|
// Normal handling for all other scalar attributes
|
||||||
$this->m_aData['m_oDefaultValue'][$sAttCode] = $value;
|
$this->m_aData['m_oDefaultValue'][$sAttCode] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetFieldsForAllowedValues()
|
public function GetFieldsForAllowedValues()
|
||||||
{
|
{
|
||||||
return $this->m_aData['m_aAllowedValuesRequested'];
|
return $this->m_aData['m_aAllowedValuesRequested'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SetAllowedValuesHtml($sAttCode, $sHtml)
|
public function SetAllowedValuesHtml($sAttCode, $sHtml)
|
||||||
{
|
{
|
||||||
// Protect against a request for a non existing field
|
// Protect against a request for a non existing field
|
||||||
if (isset($this->m_aData['m_oFieldsMap'][$sAttCode]))
|
if (isset($this->m_aData['m_oFieldsMap'][$sAttCode])) {
|
||||||
{
|
|
||||||
$this->m_aData['m_oAllowedValues'][$sAttCode] = $sHtml;
|
$this->m_aData['m_oAllowedValues'][$sAttCode] = $sHtml;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ToJSON()
|
public function ToJSON()
|
||||||
{
|
{
|
||||||
return json_encode($this->m_aData);
|
return json_encode($this->m_aData);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function FromJSON($sJSON)
|
public static function FromJSON($sJSON)
|
||||||
{
|
{
|
||||||
$oWizHelper = new WizardHelper();
|
$oWizHelper = new WizardHelper();
|
||||||
$aData = json_decode($sJSON, true); // true means hash array instead of object
|
$aData = json_decode($sJSON, true); // true means hash array instead of object
|
||||||
$oWizHelper->m_aData = $aData;
|
$oWizHelper->m_aData = $aData;
|
||||||
return $oWizHelper;
|
return $oWizHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function GetLinkedWizardStructure($oAttDef)
|
protected function GetLinkedWizardStructure($oAttDef)
|
||||||
{
|
{
|
||||||
$oWizard = new UIWizard(null, $oAttDef->GetLinkedClass());
|
$oWizard = new UIWizard(null, $oAttDef->GetLinkedClass());
|
||||||
$aWizardSteps = $oWizard->GetWizardStructure();
|
$aWizardSteps = $oWizard->GetWizardStructure();
|
||||||
$aFields = array();
|
$aFields = [];
|
||||||
$sExtKeyToMeCode = $oAttDef->GetExtKeyToMe();
|
$sExtKeyToMeCode = $oAttDef->GetExtKeyToMe();
|
||||||
// Retrieve as a flat list, all the attributes that are needed to create
|
// Retrieve as a flat list, all the attributes that are needed to create
|
||||||
// an object of the linked class and put them into a flat array, except
|
// an object of the linked class and put them into a flat array, except
|
||||||
// the attribute 'ext_key_to_me' which is a constant in our case
|
// the attribute 'ext_key_to_me' which is a constant in our case
|
||||||
foreach($aWizardSteps as $sDummy => $aMainSteps)
|
foreach ($aWizardSteps as $sDummy => $aMainSteps) {
|
||||||
{
|
|
||||||
// 2 entries: 'mandatory' and 'optional'
|
// 2 entries: 'mandatory' and 'optional'
|
||||||
foreach($aMainSteps as $aSteps)
|
foreach ($aMainSteps as $aSteps) {
|
||||||
{
|
|
||||||
// One entry for each step of the wizard
|
// One entry for each step of the wizard
|
||||||
foreach($aSteps as $sAttCode)
|
foreach ($aSteps as $sAttCode) {
|
||||||
{
|
if ($sAttCode != $sExtKeyToMeCode) {
|
||||||
if ($sAttCode != $sExtKeyToMeCode)
|
|
||||||
{
|
|
||||||
$aFields[] = $sAttCode;
|
$aFields[] = $sAttCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -310,35 +250,34 @@ class WizardHelper
|
|||||||
}
|
}
|
||||||
return $aFields;
|
return $aFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetTargetClass()
|
public function GetTargetClass()
|
||||||
{
|
{
|
||||||
return $this->m_aData['m_sClass'];
|
return $this->m_aData['m_sClass'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetFormPrefix()
|
public function GetFormPrefix()
|
||||||
{
|
{
|
||||||
return $this->m_aData['m_sFormPrefix'];
|
return $this->m_aData['m_sFormPrefix'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetInitialState()
|
public function GetInitialState()
|
||||||
{
|
{
|
||||||
return isset($this->m_aData['m_sInitialState']) ? $this->m_aData['m_sInitialState'] : null;
|
return isset($this->m_aData['m_sInitialState']) ? $this->m_aData['m_sInitialState'] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function GetStimulus()
|
||||||
|
{
|
||||||
|
return isset($this->m_aData['m_sStimulus']) ? $this->m_aData['m_sStimulus'] : null;
|
||||||
|
}
|
||||||
|
|
||||||
public function GetStimulus()
|
|
||||||
{
|
|
||||||
return isset($this->m_aData['m_sStimulus']) ? $this->m_aData['m_sStimulus'] : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetIdForField($sFieldName)
|
public function GetIdForField($sFieldName)
|
||||||
{
|
{
|
||||||
$sResult = '';
|
$sResult = '';
|
||||||
// It may happen that the field we'd like to update does not
|
// It may happen that the field we'd like to update does not
|
||||||
// exist in the form. For example, if the field should be hidden/read-only
|
// exist in the form. For example, if the field should be hidden/read-only
|
||||||
// in the current state of the object
|
// in the current state of the object
|
||||||
if (isset($this->m_aData['m_oFieldsMap'][$sFieldName]))
|
if (isset($this->m_aData['m_oFieldsMap'][$sFieldName])) {
|
||||||
{
|
|
||||||
$sResult = $this->m_aData['m_oFieldsMap'][$sFieldName];
|
$sResult = $this->m_aData['m_oFieldsMap'][$sFieldName];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,12 +317,14 @@ JS;
|
|||||||
$sWizardHelperJsVar = (!is_null($this->m_aData['m_sWizHelperJsVarName'])) ? utils::Sanitize($this->m_aData['m_sWizHelperJsVarName'], '', utils::ENUM_SANITIZATION_FILTER_PARAMETER) : 'oWizardHelper'.$this->GetFormPrefix();
|
$sWizardHelperJsVar = (!is_null($this->m_aData['m_sWizHelperJsVarName'])) ? utils::Sanitize($this->m_aData['m_sWizHelperJsVarName'], '', utils::ENUM_SANITIZATION_FILTER_PARAMETER) : 'oWizardHelper'.$this->GetFormPrefix();
|
||||||
$sWizardHelperJson = $this->ToJSON();
|
$sWizardHelperJson = $this->ToJSON();
|
||||||
|
|
||||||
$oPage->add_script(<<<JS
|
$oPage->add_script(
|
||||||
|
<<<JS
|
||||||
{$sWizardHelperJsVar}.m_oData = {$sWizardHelperJson};
|
{$sWizardHelperJsVar}.m_oData = {$sWizardHelperJson};
|
||||||
{$sWizardHelperJsVar}.UpdateFields();
|
{$sWizardHelperJsVar}.UpdateFields();
|
||||||
JS
|
JS
|
||||||
);
|
);
|
||||||
$oPage->add_ready_script(<<<JS
|
$oPage->add_ready_script(
|
||||||
|
<<<JS
|
||||||
if ({$sWizardHelperJsVar}.m_oDependenciesUpdatedPromiseResolve !== null){
|
if ({$sWizardHelperJsVar}.m_oDependenciesUpdatedPromiseResolve !== null){
|
||||||
{$sWizardHelperJsVar}.m_oDependenciesUpdatedPromiseResolve();
|
{$sWizardHelperJsVar}.m_oDependenciesUpdatedPromiseResolve();
|
||||||
}
|
}
|
||||||
@@ -396,7 +337,7 @@ JS
|
|||||||
* Function with an old pattern of code
|
* Function with an old pattern of code
|
||||||
* @deprecated 3.1.0
|
* @deprecated 3.1.0
|
||||||
*/
|
*/
|
||||||
static function ParseJsonSet($oMe, $sLinkClass, $sExtKeyToMe, $sJsonSet)
|
public static function ParseJsonSet($oMe, $sLinkClass, $sExtKeyToMe, $sJsonSet)
|
||||||
{
|
{
|
||||||
$aSet = json_decode($sJsonSet, true); // true means hash array instead of object
|
$aSet = json_decode($sJsonSet, true); // true means hash array instead of object
|
||||||
$oSet = CMDBObjectSet::FromScratch($sLinkClass);
|
$oSet = CMDBObjectSet::FromScratch($sLinkClass);
|
||||||
@@ -404,8 +345,7 @@ JS
|
|||||||
$oLink = MetaModel::NewObject($sLinkClass);
|
$oLink = MetaModel::NewObject($sLinkClass);
|
||||||
foreach ($aLinkObj as $sAttCode => $value) {
|
foreach ($aLinkObj as $sAttCode => $value) {
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sLinkClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sLinkClass, $sAttCode);
|
||||||
if (($oAttDef->IsExternalKey()) && ($value != '') && ($value > 0))
|
if (($oAttDef->IsExternalKey()) && ($value != '') && ($value > 0)) {
|
||||||
{
|
|
||||||
// For external keys: load the target object so that external fields
|
// For external keys: load the target object so that external fields
|
||||||
// get filled too
|
// get filled too
|
||||||
$oTargetObj = MetaModel::GetObject($oAttDef->GetTargetClass(), $value);
|
$oTargetObj = MetaModel::GetObject($oAttDef->GetTargetClass(), $value);
|
||||||
|
|||||||
@@ -1,43 +1,51 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/* @author Mark Jones
|
/* @author Mark Jones
|
||||||
* @license MIT License
|
* @license MIT License
|
||||||
* */
|
* */
|
||||||
|
|
||||||
if (!class_exists('ZipArchive')) { throw new Exception('ZipArchive not found'); }
|
if (!class_exists('ZipArchive')) {
|
||||||
|
throw new Exception('ZipArchive not found');
|
||||||
|
}
|
||||||
|
|
||||||
Class XLSXWriter
|
class XLSXWriter
|
||||||
{
|
{
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
protected $author ='Doc Author';
|
protected $author = 'Doc Author';
|
||||||
protected $sheets_meta = array();
|
protected $sheets_meta = [];
|
||||||
protected $shared_strings = array();//unique set
|
protected $shared_strings = [];//unique set
|
||||||
protected $shared_string_count = 0;//count of non-unique references to the unique set
|
protected $shared_string_count = 0;//count of non-unique references to the unique set
|
||||||
protected $temp_files = array();
|
protected $temp_files = [];
|
||||||
protected $date_format = 'YYYY-MM-DD';
|
protected $date_format = 'YYYY-MM-DD';
|
||||||
protected $date_time_format = 'YYYY-MM-DD\ HH:MM:SS';
|
protected $date_time_format = 'YYYY-MM-DD\ HH:MM:SS';
|
||||||
|
|
||||||
public function __construct(){}
|
public function __construct()
|
||||||
public function setAuthor($author='') { $this->author=$author; }
|
{
|
||||||
|
}
|
||||||
|
public function setAuthor($author = '')
|
||||||
|
{
|
||||||
|
$this->author = $author;
|
||||||
|
}
|
||||||
|
|
||||||
public function __destruct()
|
public function __destruct()
|
||||||
{
|
{
|
||||||
if (!empty($this->temp_files)) {
|
if (!empty($this->temp_files)) {
|
||||||
foreach($this->temp_files as $temp_file) {
|
foreach ($this->temp_files as $temp_file) {
|
||||||
@unlink($temp_file);
|
@unlink($temp_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setDateFormat($date_format)
|
public function setDateFormat($date_format)
|
||||||
{
|
{
|
||||||
$this->date_format = $date_format;
|
$this->date_format = $date_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setDateTimeFormat($date_time_format)
|
public function setDateTimeFormat($date_time_format)
|
||||||
{
|
{
|
||||||
$this->date_time_format = $date_time_format;
|
$this->date_time_format = $date_time_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function tempFilename()
|
protected function tempFilename()
|
||||||
{
|
{
|
||||||
$filename = tempnam(SetupUtils::GettmpDir(), 'xlsx_writer_');
|
$filename = tempnam(SetupUtils::GettmpDir(), 'xlsx_writer_');
|
||||||
@@ -64,120 +72,123 @@ Class XLSXWriter
|
|||||||
{
|
{
|
||||||
@unlink($filename);//if the zip already exists, overwrite it
|
@unlink($filename);//if the zip already exists, overwrite it
|
||||||
$zip = new ZipArchive();
|
$zip = new ZipArchive();
|
||||||
if (empty($this->sheets_meta)) { self::log("Error in ".__CLASS__."::".__FUNCTION__.", no worksheets defined."); return; }
|
if (empty($this->sheets_meta)) {
|
||||||
if (!$zip->open($filename, ZipArchive::CREATE)) { self::log("Error in ".__CLASS__."::".__FUNCTION__.", unable to create zip."); return; }
|
self::log("Error in ".__CLASS__."::".__FUNCTION__.", no worksheets defined.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!$zip->open($filename, ZipArchive::CREATE)) {
|
||||||
|
self::log("Error in ".__CLASS__."::".__FUNCTION__.", unable to create zip.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$zip->addEmptyDir("docProps/");
|
$zip->addEmptyDir("docProps/");
|
||||||
$zip->addFromString("docProps/app.xml" , self::buildAppXML() );
|
$zip->addFromString("docProps/app.xml", self::buildAppXML());
|
||||||
$zip->addFromString("docProps/core.xml", self::buildCoreXML());
|
$zip->addFromString("docProps/core.xml", self::buildCoreXML());
|
||||||
|
|
||||||
$zip->addEmptyDir("_rels/");
|
$zip->addEmptyDir("_rels/");
|
||||||
$zip->addFromString("_rels/.rels", self::buildRelationshipsXML());
|
$zip->addFromString("_rels/.rels", self::buildRelationshipsXML());
|
||||||
|
|
||||||
$zip->addEmptyDir("xl/worksheets/");
|
$zip->addEmptyDir("xl/worksheets/");
|
||||||
foreach($this->sheets_meta as $sheet_meta) {
|
foreach ($this->sheets_meta as $sheet_meta) {
|
||||||
$zip->addFile($sheet_meta['filename'], "xl/worksheets/".$sheet_meta['xmlname'] );
|
$zip->addFile($sheet_meta['filename'], "xl/worksheets/".$sheet_meta['xmlname']);
|
||||||
}
|
}
|
||||||
if (!empty($this->shared_strings)) {
|
if (!empty($this->shared_strings)) {
|
||||||
$zip->addFile($this->writeSharedStringsXML(), "xl/sharedStrings.xml" ); //$zip->addFromString("xl/sharedStrings.xml", self::buildSharedStringsXML() );
|
$zip->addFile($this->writeSharedStringsXML(), "xl/sharedStrings.xml"); //$zip->addFromString("xl/sharedStrings.xml", self::buildSharedStringsXML() );
|
||||||
}
|
}
|
||||||
$zip->addFromString("xl/workbook.xml" , self::buildWorkbookXML() );
|
$zip->addFromString("xl/workbook.xml", self::buildWorkbookXML());
|
||||||
$zip->addFile($this->writeStylesXML(), "xl/styles.xml" ); //$zip->addFromString("xl/styles.xml" , self::buildStylesXML() );
|
$zip->addFile($this->writeStylesXML(), "xl/styles.xml"); //$zip->addFromString("xl/styles.xml" , self::buildStylesXML() );
|
||||||
$zip->addFromString("[Content_Types].xml" , self::buildContentTypesXML() );
|
$zip->addFromString("[Content_Types].xml", self::buildContentTypesXML());
|
||||||
|
|
||||||
$zip->addEmptyDir("xl/_rels/");
|
$zip->addEmptyDir("xl/_rels/");
|
||||||
$zip->addFromString("xl/_rels/workbook.xml.rels", self::buildWorkbookRelsXML() );
|
$zip->addFromString("xl/_rels/workbook.xml.rels", self::buildWorkbookRelsXML());
|
||||||
$zip->close();
|
$zip->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function writeSheet(array $data, $sheet_name = '', array $header_types = [], array $header_row = [])
|
||||||
public function writeSheet(array $data, $sheet_name='', array $header_types=array(), array $header_row=array() )
|
|
||||||
{
|
{
|
||||||
$data = empty($data) ? array( array('') ) : $data;
|
$data = empty($data) ? [ [''] ] : $data;
|
||||||
|
|
||||||
$sheet_filename = $this->tempFilename();
|
$sheet_filename = $this->tempFilename();
|
||||||
$sheet_default = 'Sheet'.(count($this->sheets_meta)+1);
|
$sheet_default = 'Sheet'.(count($this->sheets_meta) + 1);
|
||||||
$sheet_name = !empty($sheet_name) ? $sheet_name : $sheet_default;
|
$sheet_name = !empty($sheet_name) ? $sheet_name : $sheet_default;
|
||||||
$this->sheets_meta[] = array('filename'=>$sheet_filename, 'sheetname'=>$sheet_name ,'xmlname'=>strtolower($sheet_default).".xml" );
|
$this->sheets_meta[] = ['filename' => $sheet_filename, 'sheetname' => $sheet_name ,'xmlname' => strtolower($sheet_default).".xml" ];
|
||||||
|
|
||||||
$header_offset = empty($header_types) ? 0 : 1;
|
$header_offset = empty($header_types) ? 0 : 1;
|
||||||
$row_count = count($data) + $header_offset;
|
$row_count = count($data) + $header_offset;
|
||||||
$column_count = count($data[self::array_first_key($data)]);
|
$column_count = count($data[self::array_first_key($data)]);
|
||||||
$max_cell = self::xlsCell( $row_count-1, $column_count-1 );
|
$max_cell = self::xlsCell($row_count - 1, $column_count - 1);
|
||||||
|
|
||||||
$tabselected = count($this->sheets_meta)==1 ? 'true' : 'false';//only first sheet is selected
|
$tabselected = count($this->sheets_meta) == 1 ? 'true' : 'false';//only first sheet is selected
|
||||||
$cell_formats_arr = empty($header_types) ? array_fill(0, $column_count, 'string') : array_values($header_types);
|
$cell_formats_arr = empty($header_types) ? array_fill(0, $column_count, 'string') : array_values($header_types);
|
||||||
if (empty($header_row) && !empty($header_types))
|
if (empty($header_row) && !empty($header_types)) {
|
||||||
{
|
$header_row = empty($header_types) ? [] : array_keys($header_types);
|
||||||
$header_row = empty($header_types) ? array() : array_keys($header_types);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$fd = fopen($sheet_filename, "w+");
|
$fd = fopen($sheet_filename, "w+");
|
||||||
if ($fd===false) { self::log("write failed in ".__CLASS__."::".__FUNCTION__."."); return; }
|
if ($fd === false) {
|
||||||
|
self::log("write failed in ".__CLASS__."::".__FUNCTION__.".");
|
||||||
fwrite($fd,'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n");
|
return;
|
||||||
fwrite($fd,'<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">');
|
}
|
||||||
fwrite($fd, '<sheetPr filterMode="false">');
|
|
||||||
fwrite($fd, '<pageSetUpPr fitToPage="false"/>');
|
fwrite($fd, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n");
|
||||||
fwrite($fd, '</sheetPr>');
|
fwrite($fd, '<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">');
|
||||||
fwrite($fd, '<dimension ref="A1:'.$max_cell.'"/>');
|
fwrite($fd, '<sheetPr filterMode="false">');
|
||||||
fwrite($fd, '<sheetViews>');
|
fwrite($fd, '<pageSetUpPr fitToPage="false"/>');
|
||||||
fwrite($fd, '<sheetView colorId="64" defaultGridColor="true" rightToLeft="false" showFormulas="false" showGridLines="true" showOutlineSymbols="true" showRowColHeaders="true" showZeros="true" tabSelected="'.$tabselected.'" topLeftCell="A1" view="normal" windowProtection="false" workbookViewId="0" zoomScale="100" zoomScaleNormal="100" zoomScalePageLayoutView="100">');
|
fwrite($fd, '</sheetPr>');
|
||||||
fwrite($fd, '<selection activeCell="A1" activeCellId="0" pane="topLeft" sqref="A1"/>');
|
fwrite($fd, '<dimension ref="A1:'.$max_cell.'"/>');
|
||||||
fwrite($fd, '</sheetView>');
|
fwrite($fd, '<sheetViews>');
|
||||||
fwrite($fd, '</sheetViews>');
|
fwrite($fd, '<sheetView colorId="64" defaultGridColor="true" rightToLeft="false" showFormulas="false" showGridLines="true" showOutlineSymbols="true" showRowColHeaders="true" showZeros="true" tabSelected="'.$tabselected.'" topLeftCell="A1" view="normal" windowProtection="false" workbookViewId="0" zoomScale="100" zoomScaleNormal="100" zoomScalePageLayoutView="100">');
|
||||||
fwrite($fd, '<cols>');
|
fwrite($fd, '<selection activeCell="A1" activeCellId="0" pane="topLeft" sqref="A1"/>');
|
||||||
fwrite($fd, '<col collapsed="false" hidden="false" max="1025" min="1" style="0" width="19"/>');
|
fwrite($fd, '</sheetView>');
|
||||||
fwrite($fd, '</cols>');
|
fwrite($fd, '</sheetViews>');
|
||||||
fwrite($fd, '<sheetData>');
|
fwrite($fd, '<cols>');
|
||||||
if (!empty($header_row))
|
fwrite($fd, '<col collapsed="false" hidden="false" max="1025" min="1" style="0" width="19"/>');
|
||||||
{
|
fwrite($fd, '</cols>');
|
||||||
|
fwrite($fd, '<sheetData>');
|
||||||
|
if (!empty($header_row)) {
|
||||||
fwrite($fd, '<row collapsed="false" customFormat="false" customHeight="false" hidden="false" ht="12.1" outlineLevel="0" r="'.(1).'">');
|
fwrite($fd, '<row collapsed="false" customFormat="false" customHeight="false" hidden="false" ht="12.1" outlineLevel="0" r="'.(1).'">');
|
||||||
foreach($header_row as $k=>$v)
|
foreach ($header_row as $k => $v) {
|
||||||
{
|
$this->writeCell($fd, 0, $k, $v, $cell_format = 'string');
|
||||||
$this->writeCell($fd, 0, $k, $v, $cell_format='string');
|
|
||||||
}
|
}
|
||||||
fwrite($fd, '</row>');
|
fwrite($fd, '</row>');
|
||||||
}
|
}
|
||||||
foreach($data as $i=>$row)
|
foreach ($data as $i => $row) {
|
||||||
{
|
fwrite($fd, '<row collapsed="false" customFormat="false" customHeight="false" hidden="false" ht="12.1" outlineLevel="0" r="'.($i + $header_offset + 1).'">');
|
||||||
fwrite($fd, '<row collapsed="false" customFormat="false" customHeight="false" hidden="false" ht="12.1" outlineLevel="0" r="'.($i+$header_offset+1).'">');
|
foreach ($row as $k => $v) {
|
||||||
foreach($row as $k=>$v)
|
$this->writeCell($fd, $i + $header_offset, $k, $v, $cell_formats_arr[$k]);
|
||||||
{
|
|
||||||
$this->writeCell($fd, $i+$header_offset, $k, $v, $cell_formats_arr[$k]);
|
|
||||||
}
|
}
|
||||||
fwrite($fd, '</row>');
|
fwrite($fd, '</row>');
|
||||||
}
|
}
|
||||||
fwrite($fd, '</sheetData>');
|
fwrite($fd, '</sheetData>');
|
||||||
fwrite($fd, '<printOptions headings="false" gridLines="false" gridLinesSet="true" horizontalCentered="false" verticalCentered="false"/>');
|
fwrite($fd, '<printOptions headings="false" gridLines="false" gridLinesSet="true" horizontalCentered="false" verticalCentered="false"/>');
|
||||||
fwrite($fd, '<pageMargins left="0.5" right="0.5" top="1.0" bottom="1.0" header="0.5" footer="0.5"/>');
|
fwrite($fd, '<pageMargins left="0.5" right="0.5" top="1.0" bottom="1.0" header="0.5" footer="0.5"/>');
|
||||||
fwrite($fd, '<pageSetup blackAndWhite="false" cellComments="none" copies="1" draft="false" firstPageNumber="1" fitToHeight="1" fitToWidth="1" horizontalDpi="300" orientation="portrait" pageOrder="downThenOver" paperSize="1" scale="100" useFirstPageNumber="true" usePrinterDefaults="false" verticalDpi="300"/>');
|
fwrite($fd, '<pageSetup blackAndWhite="false" cellComments="none" copies="1" draft="false" firstPageNumber="1" fitToHeight="1" fitToWidth="1" horizontalDpi="300" orientation="portrait" pageOrder="downThenOver" paperSize="1" scale="100" useFirstPageNumber="true" usePrinterDefaults="false" verticalDpi="300"/>');
|
||||||
fwrite($fd, '<headerFooter differentFirst="false" differentOddEven="false">');
|
fwrite($fd, '<headerFooter differentFirst="false" differentOddEven="false">');
|
||||||
fwrite($fd, '<oddHeader>&C&"Times New Roman,Regular"&12&A</oddHeader>');
|
fwrite($fd, '<oddHeader>&C&"Times New Roman,Regular"&12&A</oddHeader>');
|
||||||
fwrite($fd, '<oddFooter>&C&"Times New Roman,Regular"&12Page &P</oddFooter>');
|
fwrite($fd, '<oddFooter>&C&"Times New Roman,Regular"&12Page &P</oddFooter>');
|
||||||
fwrite($fd, '</headerFooter>');
|
fwrite($fd, '</headerFooter>');
|
||||||
fwrite($fd,'</worksheet>');
|
fwrite($fd, '</worksheet>');
|
||||||
fclose($fd);
|
fclose($fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function writeCell($fd, $row_number, $column_number, $value, $cell_format)
|
protected function writeCell($fd, $row_number, $column_number, $value, $cell_format)
|
||||||
{
|
{
|
||||||
static $styles = array('money'=>1,'dollar'=>1,'datetime'=>2,'date'=>3,'string'=>0);
|
static $styles = ['money' => 1,'dollar' => 1,'datetime' => 2,'date' => 3,'string' => 0];
|
||||||
$cell = self::xlsCell($row_number, $column_number);
|
$cell = self::xlsCell($row_number, $column_number);
|
||||||
$s = isset($styles[$cell_format]) && ($value !== '') ? $styles[$cell_format] : '0';
|
$s = isset($styles[$cell_format]) && ($value !== '') ? $styles[$cell_format] : '0';
|
||||||
|
|
||||||
if (is_int($value) || is_float($value)) {
|
if (is_int($value) || is_float($value)) {
|
||||||
fwrite($fd,'<c r="'.$cell.'" s="'.$s.'" t="n"><v>'.($value*1).'</v></c>');//int,float, etc
|
fwrite($fd, '<c r="'.$cell.'" s="'.$s.'" t="n"><v>'.($value * 1).'</v></c>');//int,float, etc
|
||||||
} else if (($cell_format=='date') && ($value != '')) {
|
} elseif (($cell_format == 'date') && ($value != '')) {
|
||||||
fwrite($fd,'<c r="'.$cell.'" s="'.$s.'" t="n"><v>'.intval(self::convert_date_time($value)).'</v></c>');
|
fwrite($fd, '<c r="'.$cell.'" s="'.$s.'" t="n"><v>'.intval(self::convert_date_time($value)).'</v></c>');
|
||||||
} else if (($cell_format=='datetime') && ($value != '')) {
|
} elseif (($cell_format == 'datetime') && ($value != '')) {
|
||||||
fwrite($fd,'<c r="'.$cell.'" s="'.$s.'" t="n"><v>'.self::convert_date_time($value).'</v></c>');
|
fwrite($fd, '<c r="'.$cell.'" s="'.$s.'" t="n"><v>'.self::convert_date_time($value).'</v></c>');
|
||||||
} else if ($value==''){
|
} elseif ($value == '') {
|
||||||
fwrite($fd,'<c r="'.$cell.'" s="'.$s.'"/>');
|
fwrite($fd, '<c r="'.$cell.'" s="'.$s.'"/>');
|
||||||
} else if ($value[0]=='='){
|
} elseif ($value[0] == '=') {
|
||||||
fwrite($fd,'<c r="'.$cell.'" s="'.$s.'" t="s"><f>'.self::xmlspecialchars($value).'</f></c>');
|
fwrite($fd, '<c r="'.$cell.'" s="'.$s.'" t="s"><f>'.self::xmlspecialchars($value).'</f></c>');
|
||||||
} else if ($value!==''){
|
} elseif ($value !== '') {
|
||||||
fwrite($fd,'<c r="'.$cell.'" s="'.$s.'" t="s"><v>'.self::xmlspecialchars($this->setSharedString($value)).'</v></c>');
|
fwrite($fd, '<c r="'.$cell.'" s="'.$s.'" t="s"><v>'.self::xmlspecialchars($this->setSharedString($value)).'</v></c>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,62 +196,65 @@ Class XLSXWriter
|
|||||||
{
|
{
|
||||||
$tempfile = $this->tempFilename();
|
$tempfile = $this->tempFilename();
|
||||||
$fd = fopen($tempfile, "w+");
|
$fd = fopen($tempfile, "w+");
|
||||||
if ($fd===false) { self::log("write failed in ".__CLASS__."::".__FUNCTION__."."); return; }
|
if ($fd === false) {
|
||||||
|
self::log("write failed in ".__CLASS__."::".__FUNCTION__.".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
fwrite($fd, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n");
|
fwrite($fd, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n");
|
||||||
fwrite($fd, '<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">');
|
fwrite($fd, '<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">');
|
||||||
fwrite($fd, '<numFmts count="4">');
|
fwrite($fd, '<numFmts count="4">');
|
||||||
fwrite($fd, '<numFmt formatCode="GENERAL" numFmtId="164"/>');
|
fwrite($fd, '<numFmt formatCode="GENERAL" numFmtId="164"/>');
|
||||||
fwrite($fd, '<numFmt formatCode="[$$-1009]#,##0.00;[RED]\-[$$-1009]#,##0.00" numFmtId="165"/>');
|
fwrite($fd, '<numFmt formatCode="[$$-1009]#,##0.00;[RED]\-[$$-1009]#,##0.00" numFmtId="165"/>');
|
||||||
fwrite($fd, '<numFmt formatCode="'.$this->date_time_format.'" numFmtId="166"/>');
|
fwrite($fd, '<numFmt formatCode="'.$this->date_time_format.'" numFmtId="166"/>');
|
||||||
fwrite($fd, '<numFmt formatCode="'.$this->date_format.'" numFmtId="167"/>');
|
fwrite($fd, '<numFmt formatCode="'.$this->date_format.'" numFmtId="167"/>');
|
||||||
fwrite($fd, '</numFmts>');
|
fwrite($fd, '</numFmts>');
|
||||||
fwrite($fd, '<fonts count="4">');
|
fwrite($fd, '<fonts count="4">');
|
||||||
fwrite($fd, '<font><name val="Arial"/><charset val="1"/><family val="2"/><sz val="10"/></font>');
|
fwrite($fd, '<font><name val="Arial"/><charset val="1"/><family val="2"/><sz val="10"/></font>');
|
||||||
fwrite($fd, '<font><name val="Arial"/><family val="0"/><sz val="10"/></font>');
|
fwrite($fd, '<font><name val="Arial"/><family val="0"/><sz val="10"/></font>');
|
||||||
fwrite($fd, '<font><name val="Arial"/><family val="0"/><sz val="10"/></font>');
|
fwrite($fd, '<font><name val="Arial"/><family val="0"/><sz val="10"/></font>');
|
||||||
fwrite($fd, '<font><name val="Arial"/><family val="0"/><sz val="10"/></font>');
|
fwrite($fd, '<font><name val="Arial"/><family val="0"/><sz val="10"/></font>');
|
||||||
fwrite($fd, '</fonts>');
|
fwrite($fd, '</fonts>');
|
||||||
fwrite($fd, '<fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills>');
|
fwrite($fd, '<fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills>');
|
||||||
fwrite($fd, '<borders count="1"><border diagonalDown="false" diagonalUp="false"><left/><right/><top/><bottom/><diagonal/></border></borders>');
|
fwrite($fd, '<borders count="1"><border diagonalDown="false" diagonalUp="false"><left/><right/><top/><bottom/><diagonal/></border></borders>');
|
||||||
fwrite($fd, '<cellStyleXfs count="15">');
|
fwrite($fd, '<cellStyleXfs count="15">');
|
||||||
fwrite($fd, '<xf applyAlignment="true" applyBorder="true" applyFont="true" applyProtection="true" borderId="0" fillId="0" fontId="0" numFmtId="164">');
|
fwrite($fd, '<xf applyAlignment="true" applyBorder="true" applyFont="true" applyProtection="true" borderId="0" fillId="0" fontId="0" numFmtId="164">');
|
||||||
fwrite($fd, '<alignment horizontal="general" indent="0" shrinkToFit="false" textRotation="0" vertical="bottom" wrapText="false"/>');
|
fwrite($fd, '<alignment horizontal="general" indent="0" shrinkToFit="false" textRotation="0" vertical="bottom" wrapText="false"/>');
|
||||||
fwrite($fd, '<protection hidden="false" locked="true"/>');
|
fwrite($fd, '<protection hidden="false" locked="true"/>');
|
||||||
fwrite($fd, '</xf>');
|
fwrite($fd, '</xf>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="0"/>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="0"/>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="2" numFmtId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="2" numFmtId="0"/>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="2" numFmtId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="2" numFmtId="0"/>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
|
||||||
//fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="43"/>');
|
//fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="43"/>');
|
||||||
//fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="41"/>');
|
//fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="41"/>');
|
||||||
//fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="44"/>');
|
//fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="44"/>');
|
||||||
//fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="42"/>');
|
//fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="42"/>');
|
||||||
//fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="9"/>');
|
//fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="9"/>');
|
||||||
fwrite($fd, '</cellStyleXfs>');
|
fwrite($fd, '</cellStyleXfs>');
|
||||||
fwrite($fd, '<cellXfs count="4">');
|
fwrite($fd, '<cellXfs count="4">');
|
||||||
fwrite($fd, '<xf applyAlignment="1" applyBorder="false" applyFont="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="164" xfId="0"><alignment wrapText="1"/></xf>');
|
fwrite($fd, '<xf applyAlignment="1" applyBorder="false" applyFont="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="164" xfId="0"><alignment wrapText="1"/></xf>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="165" xfId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="165" xfId="0"/>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="166" xfId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="166" xfId="0"/>');
|
||||||
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="167" xfId="0"/>');
|
fwrite($fd, '<xf applyAlignment="false" applyBorder="false" applyFont="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="167" xfId="0"/>');
|
||||||
fwrite($fd, '</cellXfs>');
|
fwrite($fd, '</cellXfs>');
|
||||||
fwrite($fd, '<cellStyles count="1">');
|
fwrite($fd, '<cellStyles count="1">');
|
||||||
fwrite($fd, '<cellStyle builtinId="0" customBuiltin="false" name="Normal" xfId="0"/>');
|
fwrite($fd, '<cellStyle builtinId="0" customBuiltin="false" name="Normal" xfId="0"/>');
|
||||||
//fwrite($fd, '<cellStyle builtinId="3" customBuiltin="false" name="Comma" xfId="15"/>');
|
//fwrite($fd, '<cellStyle builtinId="3" customBuiltin="false" name="Comma" xfId="15"/>');
|
||||||
//fwrite($fd, '<cellStyle builtinId="6" customBuiltin="false" name="Comma [0]" xfId="16"/>');
|
//fwrite($fd, '<cellStyle builtinId="6" customBuiltin="false" name="Comma [0]" xfId="16"/>');
|
||||||
//fwrite($fd, '<cellStyle builtinId="4" customBuiltin="false" name="Currency" xfId="17"/>');
|
//fwrite($fd, '<cellStyle builtinId="4" customBuiltin="false" name="Currency" xfId="17"/>');
|
||||||
//fwrite($fd, '<cellStyle builtinId="7" customBuiltin="false" name="Currency [0]" xfId="18"/>');
|
//fwrite($fd, '<cellStyle builtinId="7" customBuiltin="false" name="Currency [0]" xfId="18"/>');
|
||||||
//fwrite($fd, '<cellStyle builtinId="5" customBuiltin="false" name="Percent" xfId="19"/>');
|
//fwrite($fd, '<cellStyle builtinId="5" customBuiltin="false" name="Percent" xfId="19"/>');
|
||||||
fwrite($fd, '</cellStyles>');
|
fwrite($fd, '</cellStyles>');
|
||||||
fwrite($fd, '</styleSheet>');
|
fwrite($fd, '</styleSheet>');
|
||||||
fclose($fd);
|
fclose($fd);
|
||||||
return $tempfile;
|
return $tempfile;
|
||||||
@@ -250,12 +264,9 @@ Class XLSXWriter
|
|||||||
{
|
{
|
||||||
// Strip control characters which Excel does not seem to like...
|
// Strip control characters which Excel does not seem to like...
|
||||||
$v = preg_replace('/[\x00-\x09\x0B\x0C\x0E-\x1F]/u', '', $v);
|
$v = preg_replace('/[\x00-\x09\x0B\x0C\x0E-\x1F]/u', '', $v);
|
||||||
if (isset($this->shared_strings[$v]))
|
if (isset($this->shared_strings[$v])) {
|
||||||
{
|
|
||||||
$string_value = $this->shared_strings[$v];
|
$string_value = $this->shared_strings[$v];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$string_value = count($this->shared_strings);
|
$string_value = count($this->shared_strings);
|
||||||
$this->shared_strings[$v] = $string_value;
|
$this->shared_strings[$v] = $string_value;
|
||||||
}
|
}
|
||||||
@@ -267,13 +278,15 @@ Class XLSXWriter
|
|||||||
{
|
{
|
||||||
$tempfile = $this->tempFilename();
|
$tempfile = $this->tempFilename();
|
||||||
$fd = fopen($tempfile, "w+");
|
$fd = fopen($tempfile, "w+");
|
||||||
if ($fd===false) { self::log("write failed in ".__CLASS__."::".__FUNCTION__."."); return; }
|
if ($fd === false) {
|
||||||
|
self::log("write failed in ".__CLASS__."::".__FUNCTION__.".");
|
||||||
fwrite($fd,'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n");
|
return;
|
||||||
fwrite($fd,'<sst count="'.($this->shared_string_count).'" uniqueCount="'.count($this->shared_strings).'" xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">');
|
}
|
||||||
foreach($this->shared_strings as $s=>$c)
|
|
||||||
{
|
fwrite($fd, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n");
|
||||||
fwrite($fd,'<si><t>'.self::xmlspecialchars($s).'</t></si>');
|
fwrite($fd, '<sst count="'.($this->shared_string_count).'" uniqueCount="'.count($this->shared_strings).'" xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">');
|
||||||
|
foreach ($this->shared_strings as $s => $c) {
|
||||||
|
fwrite($fd, '<si><t>'.self::xmlspecialchars($s).'</t></si>');
|
||||||
}
|
}
|
||||||
fwrite($fd, '</sst>');
|
fwrite($fd, '</sst>');
|
||||||
fclose($fd);
|
fclose($fd);
|
||||||
@@ -282,89 +295,89 @@ Class XLSXWriter
|
|||||||
|
|
||||||
protected function buildAppXML()
|
protected function buildAppXML()
|
||||||
{
|
{
|
||||||
$app_xml="";
|
$app_xml = "";
|
||||||
$app_xml.='<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n";
|
$app_xml .= '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n";
|
||||||
$app_xml.='<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><TotalTime>0</TotalTime></Properties>';
|
$app_xml .= '<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><TotalTime>0</TotalTime></Properties>';
|
||||||
return $app_xml;
|
return $app_xml;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildCoreXML()
|
protected function buildCoreXML()
|
||||||
{
|
{
|
||||||
$core_xml="";
|
$core_xml = "";
|
||||||
$core_xml.='<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n";
|
$core_xml .= '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n";
|
||||||
$core_xml.='<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">';
|
$core_xml .= '<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">';
|
||||||
$core_xml.='<dcterms:created xsi:type="dcterms:W3CDTF">'.date("Y-m-d\TH:i:s.00\Z").'</dcterms:created>';//$date_time = '2013-07-25T15:54:37.00Z';
|
$core_xml .= '<dcterms:created xsi:type="dcterms:W3CDTF">'.date("Y-m-d\TH:i:s.00\Z").'</dcterms:created>';//$date_time = '2013-07-25T15:54:37.00Z';
|
||||||
$core_xml.='<dc:creator>'.self::xmlspecialchars($this->author).'</dc:creator>';
|
$core_xml .= '<dc:creator>'.self::xmlspecialchars($this->author).'</dc:creator>';
|
||||||
$core_xml.='<cp:revision>0</cp:revision>';
|
$core_xml .= '<cp:revision>0</cp:revision>';
|
||||||
$core_xml.='</cp:coreProperties>';
|
$core_xml .= '</cp:coreProperties>';
|
||||||
return $core_xml;
|
return $core_xml;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildRelationshipsXML()
|
protected function buildRelationshipsXML()
|
||||||
{
|
{
|
||||||
$rels_xml="";
|
$rels_xml = "";
|
||||||
$rels_xml.='<?xml version="1.0" encoding="UTF-8"?>'."\n";
|
$rels_xml .= '<?xml version="1.0" encoding="UTF-8"?>'."\n";
|
||||||
$rels_xml.='<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">';
|
$rels_xml .= '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">';
|
||||||
$rels_xml.='<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>';
|
$rels_xml .= '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>';
|
||||||
$rels_xml.='<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>';
|
$rels_xml .= '<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>';
|
||||||
$rels_xml.='<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>';
|
$rels_xml .= '<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>';
|
||||||
$rels_xml.="\n";
|
$rels_xml .= "\n";
|
||||||
$rels_xml.='</Relationships>';
|
$rels_xml .= '</Relationships>';
|
||||||
return $rels_xml;
|
return $rels_xml;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildWorkbookXML()
|
protected function buildWorkbookXML()
|
||||||
{
|
{
|
||||||
$workbook_xml="";
|
$workbook_xml = "";
|
||||||
$workbook_xml.='<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n";
|
$workbook_xml .= '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n";
|
||||||
$workbook_xml.='<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">';
|
$workbook_xml .= '<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">';
|
||||||
$workbook_xml.='<fileVersion appName="Calc"/><workbookPr backupFile="false" showObjects="all" date1904="false"/><workbookProtection/>';
|
$workbook_xml .= '<fileVersion appName="Calc"/><workbookPr backupFile="false" showObjects="all" date1904="false"/><workbookProtection/>';
|
||||||
$workbook_xml.='<bookViews><workbookView activeTab="0" firstSheet="0" showHorizontalScroll="true" showSheetTabs="true" showVerticalScroll="true" tabRatio="212" windowHeight="8192" windowWidth="16384" xWindow="0" yWindow="0"/></bookViews>';
|
$workbook_xml .= '<bookViews><workbookView activeTab="0" firstSheet="0" showHorizontalScroll="true" showSheetTabs="true" showVerticalScroll="true" tabRatio="212" windowHeight="8192" windowWidth="16384" xWindow="0" yWindow="0"/></bookViews>';
|
||||||
$workbook_xml.='<sheets>';
|
$workbook_xml .= '<sheets>';
|
||||||
foreach($this->sheets_meta as $i=>$sheet_meta) {
|
foreach ($this->sheets_meta as $i => $sheet_meta) {
|
||||||
$workbook_xml.='<sheet name="'.self::xmlspecialchars($sheet_meta['sheetname']).'" sheetId="'.($i+1).'" state="visible" r:id="rId'.($i+2).'"/>';
|
$workbook_xml .= '<sheet name="'.self::xmlspecialchars($sheet_meta['sheetname']).'" sheetId="'.($i + 1).'" state="visible" r:id="rId'.($i + 2).'"/>';
|
||||||
}
|
}
|
||||||
$workbook_xml.='</sheets>';
|
$workbook_xml .= '</sheets>';
|
||||||
$workbook_xml.='<calcPr iterateCount="100" refMode="A1" iterate="false" iterateDelta="0.001"/></workbook>';
|
$workbook_xml .= '<calcPr iterateCount="100" refMode="A1" iterate="false" iterateDelta="0.001"/></workbook>';
|
||||||
return $workbook_xml;
|
return $workbook_xml;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildWorkbookRelsXML()
|
protected function buildWorkbookRelsXML()
|
||||||
{
|
{
|
||||||
$wkbkrels_xml="";
|
$wkbkrels_xml = "";
|
||||||
$wkbkrels_xml.='<?xml version="1.0" encoding="UTF-8"?>'."\n";
|
$wkbkrels_xml .= '<?xml version="1.0" encoding="UTF-8"?>'."\n";
|
||||||
$wkbkrels_xml.='<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">';
|
$wkbkrels_xml .= '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">';
|
||||||
$wkbkrels_xml.='<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>';
|
$wkbkrels_xml .= '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>';
|
||||||
foreach($this->sheets_meta as $i=>$sheet_meta) {
|
foreach ($this->sheets_meta as $i => $sheet_meta) {
|
||||||
$wkbkrels_xml.='<Relationship Id="rId'.($i+2).'" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/'.($sheet_meta['xmlname']).'"/>';
|
$wkbkrels_xml .= '<Relationship Id="rId'.($i + 2).'" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/'.($sheet_meta['xmlname']).'"/>';
|
||||||
}
|
}
|
||||||
if (!empty($this->shared_strings)) {
|
if (!empty($this->shared_strings)) {
|
||||||
$wkbkrels_xml.='<Relationship Id="rId'.(count($this->sheets_meta)+2).'" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/>';
|
$wkbkrels_xml .= '<Relationship Id="rId'.(count($this->sheets_meta) + 2).'" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/>';
|
||||||
}
|
}
|
||||||
$wkbkrels_xml.="\n";
|
$wkbkrels_xml .= "\n";
|
||||||
$wkbkrels_xml.='</Relationships>';
|
$wkbkrels_xml .= '</Relationships>';
|
||||||
return $wkbkrels_xml;
|
return $wkbkrels_xml;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildContentTypesXML()
|
protected function buildContentTypesXML()
|
||||||
{
|
{
|
||||||
$content_types_xml="";
|
$content_types_xml = "";
|
||||||
$content_types_xml.='<?xml version="1.0" encoding="UTF-8"?>'."\n";
|
$content_types_xml .= '<?xml version="1.0" encoding="UTF-8"?>'."\n";
|
||||||
$content_types_xml.='<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">';
|
$content_types_xml .= '<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">';
|
||||||
$content_types_xml.='<Override PartName="/_rels/.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>';
|
$content_types_xml .= '<Override PartName="/_rels/.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>';
|
||||||
$content_types_xml.='<Override PartName="/xl/_rels/workbook.xml.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>';
|
$content_types_xml .= '<Override PartName="/xl/_rels/workbook.xml.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>';
|
||||||
foreach($this->sheets_meta as $i=>$sheet_meta) {
|
foreach ($this->sheets_meta as $i => $sheet_meta) {
|
||||||
$content_types_xml.='<Override PartName="/xl/worksheets/'.($sheet_meta['xmlname']).'" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>';
|
$content_types_xml .= '<Override PartName="/xl/worksheets/'.($sheet_meta['xmlname']).'" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>';
|
||||||
}
|
}
|
||||||
if (!empty($this->shared_strings)) {
|
if (!empty($this->shared_strings)) {
|
||||||
$content_types_xml.='<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>';
|
$content_types_xml .= '<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>';
|
||||||
}
|
}
|
||||||
$content_types_xml.='<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>';
|
$content_types_xml .= '<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>';
|
||||||
$content_types_xml.='<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>';
|
$content_types_xml .= '<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>';
|
||||||
$content_types_xml.='<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>';
|
$content_types_xml .= '<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>';
|
||||||
$content_types_xml.='<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>';
|
$content_types_xml .= '<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>';
|
||||||
$content_types_xml.="\n";
|
$content_types_xml .= "\n";
|
||||||
$content_types_xml.='</Types>';
|
$content_types_xml .= '</Types>';
|
||||||
return $content_types_xml;
|
return $content_types_xml;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,10 +390,10 @@ Class XLSXWriter
|
|||||||
public static function xlsCell($row_number, $column_number)
|
public static function xlsCell($row_number, $column_number)
|
||||||
{
|
{
|
||||||
$n = $column_number;
|
$n = $column_number;
|
||||||
for($r = ""; $n >= 0; $n = intval($n / 26) - 1) {
|
for ($r = ""; $n >= 0; $n = intval($n / 26) - 1) {
|
||||||
$r = chr($n%26 + 0x41) . $r;
|
$r = chr($n % 26 + 0x41).$r;
|
||||||
}
|
}
|
||||||
return $r . ($row_number+1);
|
return $r.($row_number + 1);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
public static function log($string)
|
public static function log($string)
|
||||||
@@ -404,26 +417,30 @@ Class XLSXWriter
|
|||||||
{
|
{
|
||||||
$days = 0; # Number of days since epoch
|
$days = 0; # Number of days since epoch
|
||||||
$seconds = 0; # Time expressed as fraction of 24h hours in seconds
|
$seconds = 0; # Time expressed as fraction of 24h hours in seconds
|
||||||
$year=$month=$day=0;
|
$year = $month = $day = 0;
|
||||||
$hour=$min =$sec=0;
|
$hour = $min = $sec = 0;
|
||||||
|
|
||||||
$date_time = $date_input;
|
$date_time = $date_input;
|
||||||
if (preg_match("/(\d{4})\-(\d{2})\-(\d{2})/", $date_time, $matches))
|
if (preg_match("/(\d{4})\-(\d{2})\-(\d{2})/", $date_time, $matches)) {
|
||||||
{
|
list($junk, $year, $month, $day) = $matches;
|
||||||
list($junk,$year,$month,$day) = $matches;
|
|
||||||
}
|
}
|
||||||
if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $date_time, $matches))
|
if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $date_time, $matches)) {
|
||||||
{
|
list($junk, $hour, $min, $sec) = $matches;
|
||||||
list($junk,$hour,$min,$sec) = $matches;
|
$seconds = ($hour * 60 * 60 + $min * 60 + $sec) / (24 * 60 * 60);
|
||||||
$seconds = ( $hour * 60 * 60 + $min * 60 + $sec ) / ( 24 * 60 * 60 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//using 1900 as epoch, not 1904, ignoring 1904 special case
|
//using 1900 as epoch, not 1904, ignoring 1904 special case
|
||||||
|
|
||||||
# Special cases for Excel.
|
# Special cases for Excel.
|
||||||
if ("$year-$month-$day"=='1899-12-31') return $seconds ; # Excel 1900 epoch
|
if ("$year-$month-$day" == '1899-12-31') {
|
||||||
if ("$year-$month-$day"=='1900-01-00') return $seconds ; # Excel 1900 epoch
|
return $seconds ;
|
||||||
if ("$year-$month-$day"=='1900-02-29') return 60 + $seconds ; # Excel false leapday
|
} # Excel 1900 epoch
|
||||||
|
if ("$year-$month-$day" == '1900-01-00') {
|
||||||
|
return $seconds ;
|
||||||
|
} # Excel 1900 epoch
|
||||||
|
if ("$year-$month-$day" == '1900-02-29') {
|
||||||
|
return 60 + $seconds ;
|
||||||
|
} # Excel false leapday
|
||||||
|
|
||||||
# We calculate the date by calculating the number of days since the epoch
|
# We calculate the date by calculating the number of days since the epoch
|
||||||
# and adjust for the number of leap days. We calculate the number of leap
|
# and adjust for the number of leap days. We calculate the number of leap
|
||||||
@@ -435,33 +452,35 @@ Class XLSXWriter
|
|||||||
$range = $year - $epoch;
|
$range = $year - $epoch;
|
||||||
|
|
||||||
# Set month days and check for leap year.
|
# Set month days and check for leap year.
|
||||||
$leap = (($year % 400 == 0) || (($year % 4 == 0) && ($year % 100)) ) ? 1 : 0;
|
$leap = (($year % 400 == 0) || (($year % 4 == 0) && ($year % 100))) ? 1 : 0;
|
||||||
$mdays = array( 31, ($leap ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
|
$mdays = [ 31, ($leap ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
|
||||||
|
|
||||||
# Some boundary checks
|
# Some boundary checks
|
||||||
if($year < $epoch || $year > 9999) return 0;
|
if ($year < $epoch || $year > 9999) {
|
||||||
if($month < 1 || $month > 12) return 0;
|
return 0;
|
||||||
if($day < 1 || $day > $mdays[ $month - 1 ]) return 0;
|
}
|
||||||
|
if ($month < 1 || $month > 12) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ($day < 1 || $day > $mdays[ $month - 1 ]) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
# Accumulate the number of days since the epoch.
|
# Accumulate the number of days since the epoch.
|
||||||
$days = $day; # Add days for current month
|
$days = $day; # Add days for current month
|
||||||
$days += array_sum( array_slice($mdays, 0, $month-1 ) ); # Add days for past months
|
$days += array_sum(array_slice($mdays, 0, $month - 1)); # Add days for past months
|
||||||
$days += $range * 365; # Add days for past years
|
$days += $range * 365; # Add days for past years
|
||||||
$days += intval( ( $range ) / 4 ); # Add leapdays
|
$days += intval(($range) / 4); # Add leapdays
|
||||||
$days -= intval( ( $range + $offset ) / 100 ); # Subtract 100 year leapdays
|
$days -= intval(($range + $offset) / 100); # Subtract 100 year leapdays
|
||||||
$days += intval( ( $range + $offset + $norm ) / 400 ); # Add 400 year leapdays
|
$days += intval(($range + $offset + $norm) / 400); # Add 400 year leapdays
|
||||||
$days -= $leap; # Already counted above
|
$days -= $leap; # Already counted above
|
||||||
|
|
||||||
# Adjust for Excel erroneously treating 1900 as a leap year.
|
# Adjust for Excel erroneously treating 1900 as a leap year.
|
||||||
if ($days > 59) { $days++;}
|
if ($days > 59) {
|
||||||
|
$days++;
|
||||||
|
}
|
||||||
|
|
||||||
return $days + $seconds;
|
return $days + $seconds;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/XMLPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/XMLPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/XMLPage.php, now loadable using autoloader');
|
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/XMLPage.php, now loadable using autoloader');
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks PHP version
|
* Checks PHP version
|
||||||
*
|
*
|
||||||
@@ -39,7 +38,6 @@ if (PHP_MAJOR_VERSION >= 7) {
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
define('ITOP_DEFAULT_ENV', 'production');
|
define('ITOP_DEFAULT_ENV', 'production');
|
||||||
define('MAINTENANCE_MODE_FILE', APPROOT.'data/.maintenance');
|
define('MAINTENANCE_MODE_FILE', APPROOT.'data/.maintenance');
|
||||||
define('READONLY_MODE_FILE', APPROOT.'data/.readonly');
|
define('READONLY_MODE_FILE', APPROOT.'data/.readonly');
|
||||||
@@ -60,8 +58,7 @@ if (!isset($bBypassMaintenance)) {
|
|||||||
$bBypassMaintenance = isset($_REQUEST['maintenance']) ? boolval($_REQUEST['maintenance']) : false;
|
$bBypassMaintenance = isset($_REQUEST['maintenance']) ? boolval($_REQUEST['maintenance']) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists(MAINTENANCE_MODE_FILE) && !$bBypassMaintenance)
|
if (file_exists(MAINTENANCE_MODE_FILE) && !$bBypassMaintenance) {
|
||||||
{
|
|
||||||
$sTitle = 'Maintenance';
|
$sTitle = 'Maintenance';
|
||||||
$sMessage = 'This application is currently under maintenance.';
|
$sMessage = 'This application is currently under maintenance.';
|
||||||
|
|
||||||
@@ -70,8 +67,7 @@ if (file_exists(MAINTENANCE_MODE_FILE) && !$bBypassMaintenance)
|
|||||||
include(APPROOT.'application/maintenancemsg.php');
|
include(APPROOT.'application/maintenancemsg.php');
|
||||||
$sSAPIName = strtoupper(trim(PHP_SAPI));
|
$sSAPIName = strtoupper(trim(PHP_SAPI));
|
||||||
|
|
||||||
switch (true)
|
switch (true) {
|
||||||
{
|
|
||||||
case isset($_SERVER['REQUEST_URI']) && EndsWith($_SERVER['REQUEST_URI'], '/pages/ajax.searchform.php'):
|
case isset($_SERVER['REQUEST_URI']) && EndsWith($_SERVER['REQUEST_URI'], '/pages/ajax.searchform.php'):
|
||||||
_MaintenanceHtmlMessage($sMessage);
|
_MaintenanceHtmlMessage($sMessage);
|
||||||
break;
|
break;
|
||||||
@@ -102,6 +98,7 @@ if (file_exists(MAINTENANCE_MODE_FILE) && !$bBypassMaintenance)
|
|||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function EndsWith($haystack, $needle) {
|
function EndsWith($haystack, $needle)
|
||||||
|
{
|
||||||
return substr_compare($haystack, $needle, -strlen($needle)) === 0;
|
return substr_compare($haystack, $needle, -strlen($needle)) === 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
echo 'Access denied';
|
echo 'Access denied';
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -67,9 +68,8 @@ class DbConnectionWrapper
|
|||||||
if (is_null($oMysqli)) {
|
if (is_null($oMysqli)) {
|
||||||
// Reset to standard connection
|
// Reset to standard connection
|
||||||
static::$oDbCnxMockableForQuery = static::$oDbCnxStandard;
|
static::$oDbCnxMockableForQuery = static::$oDbCnxStandard;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
static::$oDbCnxMockableForQuery = $oMysqli;
|
static::$oDbCnxMockableForQuery = $oMysqli;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user