mirror of
https://github.com/Combodo/iTop.git
synced 2026-06-01 13:42:17 +02:00
Release 0.9 of iTop
SVN:0.9[309]
This commit is contained in:
444
addons/userrights/userrightsmatrix.class.inc.php
Normal file
444
addons/userrights/userrightsmatrix.class.inc.php
Normal file
@@ -0,0 +1,444 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UserRightsMatrix
|
||||
* User management Module
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
|
||||
class UserRightsMatrixUsers extends DBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights",
|
||||
"name" => "user",
|
||||
"description" => "users and credentials",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "login",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_ur_matrixusers",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("userid", array("label"=>"User id", "description"=>"User identifier (depends on the business model)", "allowed_values"=>null, "sql"=>"userid", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("login", array("label"=>"login", "description"=>"user identification string", "allowed_values"=>null, "sql"=>"login", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("password", array("label"=>"password", "description"=>"user authentication string", "allowed_values"=>null, "sql"=>"pwd", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("userid");
|
||||
MetaModel::Init_AddFilterFromAttribute("login");
|
||||
}
|
||||
}
|
||||
|
||||
class UserRightsMatrixClassGrant extends DBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights",
|
||||
"name" => "class_permission",
|
||||
"description" => "permissions on classes",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_ur_matrixclasses",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"UserRightsMatrixUsers", "jointype"=> "", "label"=>"user", "description"=>"user account", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("label"=>"Login", "description"=>"Login", "allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("class", array("label"=>"class", "description"=>"class name", "allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("action", array("label"=>"action", "description"=>"operations to perform on the given class", "allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("label"=>"permission", "description"=>"allowed or not allowed?", "allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("userid");
|
||||
MetaModel::Init_AddFilterFromAttribute("login");
|
||||
MetaModel::Init_AddFilterFromAttribute("class");
|
||||
MetaModel::Init_AddFilterFromAttribute("action");
|
||||
}
|
||||
}
|
||||
|
||||
class UserRightsMatrixClassStimulusGrant extends DBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights",
|
||||
"name" => "stimulus_permission",
|
||||
"description" => "permissions on stimilus in the life cycle of the object",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_ur_matrixclassesstimulus",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"UserRightsMatrixUsers", "jointype"=> "", "label"=>"user", "description"=>"user account", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("label"=>"Login", "description"=>"Login", "allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("class", array("label"=>"class", "description"=>"class name", "allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("stimulus", array("label"=>"action", "description"=>"operations to perform on the given class", "allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("label"=>"permission", "description"=>"allowed or not allowed?", "allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("userid");
|
||||
MetaModel::Init_AddFilterFromAttribute("login");
|
||||
MetaModel::Init_AddFilterFromAttribute("class");
|
||||
MetaModel::Init_AddFilterFromAttribute("stimulus");
|
||||
}
|
||||
}
|
||||
|
||||
class UserRightsMatrixAttributeGrant extends DBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights",
|
||||
"name" => "attribute_permission",
|
||||
"description" => "permissions at the attributes level",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_ur_matrixattributes",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"UserRightsMatrixUsers", "jointype"=> "", "label"=>"user", "description"=>"user account", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("label"=>"Login", "description"=>"Login", "allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("class", array("label"=>"class", "description"=>"class name", "allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("attcode", array("label"=>"attribute", "description"=>"attribute code", "allowed_values"=>null, "sql"=>"attcode", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("action", array("label"=>"action", "description"=>"operations to perform on the given class", "allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("label"=>"permission", "description"=>"allowed or not allowed?", "allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("userid");
|
||||
MetaModel::Init_AddFilterFromAttribute("login");
|
||||
MetaModel::Init_AddFilterFromAttribute("class");
|
||||
MetaModel::Init_AddFilterFromAttribute("attcode");
|
||||
MetaModel::Init_AddFilterFromAttribute("action");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class UserRightsMatrix extends UserRightsAddOnAPI
|
||||
{
|
||||
static public $m_aActionCodes = array(
|
||||
UR_ACTION_READ => 'read',
|
||||
UR_ACTION_MODIFY => 'modify',
|
||||
UR_ACTION_DELETE => 'delete',
|
||||
UR_ACTION_BULK_READ => 'bulk read',
|
||||
UR_ACTION_BULK_MODIFY => 'bulk modify',
|
||||
UR_ACTION_BULK_DELETE => 'bulk delete',
|
||||
);
|
||||
|
||||
// Installation: create the very first user
|
||||
public function CreateAdministrator($sAdminUser, $sAdminPwd)
|
||||
{
|
||||
// Maybe we should check that no other user with userid == 0 exists
|
||||
$oUser = new UserRightsMatrixUsers();
|
||||
$oUser->Set('login', $sAdminUser);
|
||||
$oUser->Set('password', $sAdminPwd);
|
||||
$oUser->Set('userid', 1); // one is for root !
|
||||
|
||||
// Create a change to record the history of the User object
|
||||
$oChange = MetaModel::NewObject("CMDBChange");
|
||||
$oChange->Set("date", time());
|
||||
$oChange->Set("userinfo", "Initialization");
|
||||
$iChangeId = $oChange->DBInsert();
|
||||
|
||||
// Now record the admin user object
|
||||
$iUserId = $oUser->DBInsertTrackedNoReload($oChange);
|
||||
$this->SetupUser($iUserId, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function IsAdministrator($iUserId)
|
||||
{
|
||||
return ($iUserId == 1);
|
||||
}
|
||||
|
||||
public function Setup()
|
||||
{
|
||||
// Users must be added manually
|
||||
// This procedure will then update the matrix when a new user is found or a new class/attribute appears
|
||||
$oUserSet = new DBObjectSet(DBObjectSearch::FromSibuSQL("UserRightsMatrixUsers"));
|
||||
while ($oUser = $oUserSet->Fetch())
|
||||
{
|
||||
$this->SetupUser($oUser->GetKey());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function SetupUser($iUserId, $bNewUser = false)
|
||||
{
|
||||
foreach(array('bizmodel', 'application', 'gui', 'core/cmdb') as $sCategory)
|
||||
{
|
||||
foreach (MetaModel::GetClasses($sCategory) as $sClass)
|
||||
{
|
||||
foreach (self::$m_aActionCodes as $iActionCode => $sAction)
|
||||
{
|
||||
if ($bNewUser)
|
||||
{
|
||||
$bAddCell = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassGrant WHERE class = '$sClass' AND action = '$sAction' AND userid = $iUserId"));
|
||||
$bAddCell = ($oSet->Count() < 1);
|
||||
}
|
||||
if ($bAddCell)
|
||||
{
|
||||
// Create a new entry
|
||||
$oMyClassGrant = MetaModel::NewObject("UserRightsMatrixClassGrant");
|
||||
$oMyClassGrant->Set("userid", $iUserId);
|
||||
$oMyClassGrant->Set("class", $sClass);
|
||||
$oMyClassGrant->Set("action", $sAction);
|
||||
$oMyClassGrant->Set("permission", "yes");
|
||||
$iId = $oMyClassGrant->DBInsertNoReload();
|
||||
}
|
||||
}
|
||||
foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $oStimulus)
|
||||
{
|
||||
if ($bNewUser)
|
||||
{
|
||||
$bAddCell = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassStimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND userid = $iUserId"));
|
||||
$bAddCell = ($oSet->Count() < 1);
|
||||
}
|
||||
if ($bAddCell)
|
||||
{
|
||||
// Create a new entry
|
||||
$oMyClassGrant = MetaModel::NewObject("UserRightsMatrixClassStimulusGrant");
|
||||
$oMyClassGrant->Set("userid", $iUserId);
|
||||
$oMyClassGrant->Set("class", $sClass);
|
||||
$oMyClassGrant->Set("stimulus", $sStimulusCode);
|
||||
$oMyClassGrant->Set("permission", "yes");
|
||||
$iId = $oMyClassGrant->DBInsertNoReload();
|
||||
}
|
||||
}
|
||||
foreach (MetaModel::GetAttributesList($sClass) as $sAttCode)
|
||||
{
|
||||
if ($bNewUser)
|
||||
{
|
||||
$bAddCell = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixAttributeGrant WHERE class = '$sClass' AND attcode = '$sAttCode' AND userid = $iUserId"));
|
||||
$bAddCell = ($oSet->Count() < 1);
|
||||
}
|
||||
if ($bAddCell)
|
||||
{
|
||||
foreach (array('read', 'modify') as $sAction)
|
||||
{
|
||||
// Create a new entry
|
||||
$oMyAttGrant = MetaModel::NewObject("UserRightsMatrixAttributeGrant");
|
||||
$oMyAttGrant->Set("userid", $iUserId);
|
||||
$oMyAttGrant->Set("class", $sClass);
|
||||
$oMyAttGrant->Set("attcode", $sAttCode);
|
||||
$oMyAttGrant->Set("action", $sAction);
|
||||
$oMyAttGrant->Set("permission", "yes");
|
||||
$iId = $oMyAttGrant->DBInsertNoReload();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Create the "My Bookmarks" menu item (parent_id = 0, rank = 6)
|
||||
if ($bNewUser)
|
||||
{
|
||||
$bAddMenu = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT menuNode WHERE type = 'user' AND parent_id = 0 AND user_id = $iUserId"));
|
||||
$bAddMenu = ($oSet->Count() < 1);
|
||||
}
|
||||
if ($bAddMenu)
|
||||
{
|
||||
$oMenu = MetaModel::NewObject('menuNode');
|
||||
$oMenu->Set('type', 'user');
|
||||
$oMenu->Set('parent_id', 0); // It's a toplevel entry
|
||||
$oMenu->Set('rank', 6); // Located just above the Admin Tools section (=7)
|
||||
$oMenu->Set('name', 'My Bookmarks');
|
||||
$oMenu->Set('label', 'My Favorite Items');
|
||||
$oMenu->Set('hyperlink', 'UI.php');
|
||||
$oMenu->Set('template', '<p></p><p></p><p style="text-align:center; font-family:Georgia, Times, serif; font-size:32px;">My bookmarks</p><p style="text-align:center; font-family:Georgia, Times, serif; font-size:14px;"><i>This section contains my most favorite search results</i></p>');
|
||||
$oMenu->Set('user_id', $iUserId);
|
||||
$oMenu->DBInsert();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function Init()
|
||||
{
|
||||
// Could be loaded in a shared memory (?)
|
||||
return true;
|
||||
}
|
||||
|
||||
public function CheckCredentials($sUserName, $sPassword)
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixUsers WHERE login = '$sUserName'"));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
// todo: throw an exception?
|
||||
return false;
|
||||
}
|
||||
|
||||
$oLogin = $oSet->Fetch();
|
||||
if ($oLogin->Get('password') == $sPassword)
|
||||
{
|
||||
return $oLogin->Get('userid');
|
||||
}
|
||||
// todo: throw an exception?
|
||||
return false;
|
||||
}
|
||||
|
||||
public function GetUserId($sUserName)
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixUsers WHERE login = '$sUserName'"));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
// todo: throw an exception?
|
||||
return false;
|
||||
}
|
||||
|
||||
$oLogin = $oSet->Fetch();
|
||||
return $oLogin->Get('userid');
|
||||
}
|
||||
|
||||
public function GetContactId($sUserName)
|
||||
{
|
||||
// this module has no link with the business data
|
||||
return null;
|
||||
}
|
||||
|
||||
public function GetFilter($sUserName, $sClass)
|
||||
{
|
||||
$oNullFilter = new DBObjectSearch($sClass);
|
||||
return $oNullFilter;
|
||||
}
|
||||
|
||||
public function IsActionAllowed($iUserId, $sClass, $iActionCode, $oInstanceSet = null)
|
||||
{
|
||||
if (!array_key_exists($iActionCode, self::$m_aActionCodes))
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
}
|
||||
$sAction = self::$m_aActionCodes[$iActionCode];
|
||||
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassGrant WHERE class = '$sClass' AND action = '$sAction' AND userid = '$iUserId'"));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
}
|
||||
|
||||
$oGrantRecord = $oSet->Fetch();
|
||||
switch ($oGrantRecord->Get('permission'))
|
||||
{
|
||||
case 'yes':
|
||||
$iRetCode = UR_ALLOWED_YES;
|
||||
break;
|
||||
case 'no':
|
||||
default:
|
||||
$iRetCode = UR_ALLOWED_NO;
|
||||
break;
|
||||
}
|
||||
return $iRetCode;
|
||||
}
|
||||
|
||||
public function IsActionAllowedOnAttribute($iUserId, $sClass, $sAttCode, $iActionCode, $oInstanceSet = null)
|
||||
{
|
||||
if (!array_key_exists($iActionCode, self::$m_aActionCodes))
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
}
|
||||
$sAction = self::$m_aActionCodes[$iActionCode];
|
||||
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixAttributeGrant WHERE class = '$sClass' AND attcode = '$sAttCode' AND action = '$sAction' AND userid = '$iUserId'"));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
}
|
||||
|
||||
$oGrantRecord = $oSet->Fetch();
|
||||
switch ($oGrantRecord->Get('permission'))
|
||||
{
|
||||
case 'yes':
|
||||
$iRetCode = UR_ALLOWED_YES;
|
||||
break;
|
||||
case 'no':
|
||||
default:
|
||||
$iRetCode = UR_ALLOWED_NO;
|
||||
break;
|
||||
}
|
||||
return $iRetCode;
|
||||
}
|
||||
|
||||
public function IsStimulusAllowed($iUserId, $sClass, $sStimulusCode, $oInstanceSet = null)
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassStimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND userid = '$iUserId'"));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
}
|
||||
|
||||
$oGrantRecord = $oSet->Fetch();
|
||||
switch ($oGrantRecord->Get('permission'))
|
||||
{
|
||||
case 'yes':
|
||||
$iRetCode = UR_ALLOWED_YES;
|
||||
break;
|
||||
case 'no':
|
||||
default:
|
||||
$iRetCode = UR_ALLOWED_NO;
|
||||
break;
|
||||
}
|
||||
return $iRetCode;
|
||||
}
|
||||
|
||||
public function FlushPrivileges()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
UserRights::SelectModule('UserRightsMatrix');
|
||||
|
||||
?>
|
||||
84
addons/userrights/userrightsnull.class.inc.php
Normal file
84
addons/userrights/userrightsnull.class.inc.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UserRightsNull
|
||||
* User management Module - say Yeah! to everything
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
|
||||
class UserRightsNull extends UserRightsAddOnAPI
|
||||
{
|
||||
// Installation: create the very first user
|
||||
public function CreateAdministrator($sAdminUser, $sAdminPwd)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function IsAdministrator($iUserId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function Setup()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function CheckCredentials($sUserName, $sPassword)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function GetUserId($sUserName)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function GetContactId($sUserName)
|
||||
{
|
||||
// this module has no link with the business data
|
||||
return null;
|
||||
}
|
||||
|
||||
public function GetFilter($sUserName, $sClass)
|
||||
{
|
||||
$oNullFilter = new DBObjectSearch($sClass);
|
||||
return $oNullFilter;
|
||||
}
|
||||
|
||||
public function IsActionAllowed($iUserId, $sClass, $iActionCode, $oInstanceSet = null)
|
||||
{
|
||||
return UR_ALLOWED_YES;
|
||||
}
|
||||
|
||||
public function IsStimulusAllowed($iUserId, $sClass, $sStimulusCode, $oInstanceSet = null)
|
||||
{
|
||||
return UR_ALLOWED_YES;
|
||||
}
|
||||
|
||||
public function IsActionAllowedOnAttribute($iUserId, $sClass, $sAttCode, $iActionCode, $oInstanceSet = null)
|
||||
{
|
||||
return UR_ALLOWED_YES;
|
||||
}
|
||||
|
||||
public function FlushPrivileges()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
UserRights::SelectModule('UserRightsNull');
|
||||
|
||||
?>
|
||||
1712
addons/userrights/userrightsprofile.class.inc.php
Normal file
1712
addons/userrights/userrightsprofile.class.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
145
application/ajaxwebpage.class.inc.php
Normal file
145
application/ajaxwebpage.class.inc.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
require_once("../application/webpage.class.inc.php");
|
||||
/**
|
||||
* Simple web page with no includes, header or fancy formatting, useful to
|
||||
* generate HTML fragments when called by an AJAX method
|
||||
*
|
||||
* @package iTopApplication
|
||||
* @access public
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <dflaven@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
*/
|
||||
|
||||
class ajax_page extends WebPage
|
||||
{
|
||||
/**
|
||||
* Jquery style ready script
|
||||
* @var Hash
|
||||
*/
|
||||
protected $m_sReadyScript;
|
||||
|
||||
/**
|
||||
* constructor for the web page
|
||||
* @param string $s_title Not used
|
||||
*/
|
||||
function __construct($s_title)
|
||||
{
|
||||
parent::__construct($s_title);
|
||||
$this->m_sReadyScript = "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Echoes the content of the whole page
|
||||
* @return void
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
foreach($this->a_headers as $s_header)
|
||||
{
|
||||
header($s_header);
|
||||
}
|
||||
$s_captured_output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
echo $this->s_content;
|
||||
if (!empty($this->m_sReadyScript))
|
||||
{
|
||||
echo "<script>\n";
|
||||
echo $this->m_sReadyScript; // Ready Scripts are output as simple scripts
|
||||
echo "</script>\n";
|
||||
}
|
||||
if (trim($s_captured_output) != "")
|
||||
{
|
||||
echo $s_captured_output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a paragraph with a smaller font into the page
|
||||
* NOT implemented (i.e does nothing)
|
||||
* @param string $sText Content of the (small) paragraph
|
||||
* @return void
|
||||
*/
|
||||
public function small_p($sText)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tabular content to the web page
|
||||
* @param Hash $aConfig Configuration of the table: hash array of 'column_id' => 'Column Label'
|
||||
* @param Hash $aData Hash array. Data to display in the table: each row is made of 'column_id' => Data. A column 'pkey' is expected for each row
|
||||
* @param Hash $aParams Hash array. Extra parameters for the table. Entry 'class' holds the class of the objects listed in the table
|
||||
* @return void
|
||||
*/
|
||||
public function table($aConfig, $aData, $aParams = array())
|
||||
{
|
||||
// WARNING WARNING WARNING
|
||||
// This whole function is actually a copy paste from iTopWebPage::table
|
||||
$oAppContext = new ApplicationContext();
|
||||
|
||||
static $iNbTables = 0;
|
||||
$iNbTables++;
|
||||
$sHtml = "";
|
||||
$sHtml .= "<table class=\"listResults\">\n";
|
||||
$sHtml .= "<thead>\n";
|
||||
$sHtml .= "<tr>\n";
|
||||
foreach($aConfig as $sName=>$aDef)
|
||||
{
|
||||
$sHtml .= "<th title=\"".$aDef['description']."\">".$aDef['label']."</th>\n";
|
||||
}
|
||||
$sHtml .= "</tr>\n";
|
||||
$sHtml .= "</thead>\n";
|
||||
$sHtml .= "<tbody>\n";
|
||||
foreach($aData as $aRow)
|
||||
{
|
||||
if (false) //(isset($aParams['preview']) && $aParams['preview'])
|
||||
{
|
||||
$sHtml .= "<tr id=\"Row_".$iNbTables."_".$aRow['key']."\" onClick=\"DisplayPreview(".$iNbTables.",".$aRow['key'].",'".$aParams['class']."')\">\n";
|
||||
}
|
||||
else if (isset($aRow['key']))
|
||||
{
|
||||
$sHtml .= "<tr onDblClick=\"DisplayDetails(".$aRow['key'].",'".$aParams['class']."')\">\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml .= "<tr>\n";
|
||||
}
|
||||
foreach($aConfig as $sName=>$aVoid)
|
||||
{
|
||||
if ($sName != 'key')
|
||||
{
|
||||
$sValue = empty($aRow[$sName]) ? ' ' : $aRow[$sName];
|
||||
$sHtml .= "<td>$sValue</td>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sUIPage = cmdbAbstractObject::ComputeUIPage($aParams['class']);
|
||||
$sHtml .= "<td><a class=\"no-arrow\" href=\"$sUIPage?operation=details&id=".$aRow['key']."&class=".$aParams['class']."&".$oAppContext->GetForLink()."\"><img src=\"../images/zoom.gif\" title=\"Details\" border=\"0\"></a></td>\n";
|
||||
}
|
||||
}
|
||||
$sHtml .= "</tr>\n";
|
||||
}
|
||||
$sHtml .= "</tbody>\n";
|
||||
$sHtml .= "</table>\n";
|
||||
if (isset($aParams['preview']) && $aParams['preview'])
|
||||
{
|
||||
$sHtml .= "<div class=\"PreviewPane\" id=\"PreviewPane_".$iNbTables."\" style=\"height:100px;border:1px solid black;margin-top:2px;padding:3px;text-align:left;display:none;\">Preview Pane</div>";
|
||||
}
|
||||
$this->add($sHtml);
|
||||
}
|
||||
/**
|
||||
* Adds a script to be executed when the DOM is ready (typical JQuery use)
|
||||
* NOT implemented in this version of the class.
|
||||
* @return void
|
||||
*/
|
||||
public function add_ready_script($sScript)
|
||||
{
|
||||
// Does nothing in ajax rendered content.. for now...
|
||||
// Maybe we should add this as a simple <script> tag at the end of the output
|
||||
// considering that at this time everything in the page is "ready"...
|
||||
$this->m_sReadyScript .= $sScript;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
15
application/application.inc.php
Normal file
15
application/application.inc.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
// Includes all the classes to have the application up and running
|
||||
require_once('../application/applicationcontext.class.inc.php');
|
||||
require_once('../application/usercontext.class.inc.php');
|
||||
require_once('../application/cmdbabstract.class.inc.php');
|
||||
require_once('../application/displayblock.class.inc.php');
|
||||
require_once('../application/audit.category.class.inc.php');
|
||||
require_once('../application/audit.rule.class.inc.php');
|
||||
//require_once('../application/menunode.class.inc.php');
|
||||
require_once('../application/utils.inc.php');
|
||||
|
||||
class ApplicationException extends CoreException
|
||||
{
|
||||
}
|
||||
?>
|
||||
99
application/applicationcontext.class.inc.php
Normal file
99
application/applicationcontext.class.inc.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
require_once("../application/utils.inc.php");
|
||||
/**
|
||||
* Helper class to store and manipulate the parameters that make the application's context
|
||||
*
|
||||
* Usage:
|
||||
* 1) Build the application's context by constructing the object
|
||||
* (the object will read some of the page's parameters)
|
||||
*
|
||||
* 2) Add these parameters to hyperlinks or to forms using the helper, functions
|
||||
* GetForLink(), GetForForm() or GetAsHash()
|
||||
*/
|
||||
class ApplicationContext
|
||||
{
|
||||
protected $aNames;
|
||||
protected $aValues;
|
||||
protected static $aDefaultValues; // Cache shared among all instances
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->aNames = array(
|
||||
'org_id', 'menu'
|
||||
);
|
||||
$this->ReadContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the context directly in the PHP parameters (either POST or GET)
|
||||
* return nothing
|
||||
*/
|
||||
protected function ReadContext()
|
||||
{
|
||||
if (empty(self::$aDefaultValues))
|
||||
{
|
||||
self::$aDefaultValues = array();
|
||||
foreach($this->aNames as $sName)
|
||||
{
|
||||
$sValue = utils::ReadParam($sName, '');
|
||||
// TO DO: check if some of the context parameters are mandatory (or have default values)
|
||||
if (!empty($sValue))
|
||||
{
|
||||
self::$aDefaultValues[$sName] = $sValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->aValues = self::$aDefaultValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public function GetForLink()
|
||||
{
|
||||
$aParams = array();
|
||||
foreach($this->aValues as $sName => $sValue)
|
||||
{
|
||||
$aParams[] = $sName.'='.urlencode($sValue);
|
||||
}
|
||||
return implode("&", $aParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the context as sequence of input tags to be inserted inside a <form> tag
|
||||
* return string The context as a sequence of <input type="hidden" /> tags
|
||||
*/
|
||||
public function GetForForm()
|
||||
{
|
||||
$sContext = "";
|
||||
foreach($this->aValues as $sName => $sValue)
|
||||
{
|
||||
$sContext .= "<input type=\"hidden\" name=\"$sName\" value=\"$sValue\" />\n";
|
||||
}
|
||||
return $sContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the context as a hash array 'parameter_name' => value
|
||||
* return array The context information
|
||||
*/
|
||||
public function GetAsHash()
|
||||
{
|
||||
return $this->aValues;
|
||||
}
|
||||
/**
|
||||
* Removes the specified parameter from the context, for example when the same parameter
|
||||
* is already a search parameter
|
||||
* @param string $sParamName Name of the parameter to remove
|
||||
* @return none
|
||||
*/
|
||||
public function Reset($sParamName)
|
||||
{
|
||||
if (isset($this->aValues[$sParamName]))
|
||||
{
|
||||
unset($this->aValues[$sParamName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
45
application/audit.category.class.inc.php
Normal file
45
application/audit.category.class.inc.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
require_once('../application/cmdbabstract.class.inc.php');
|
||||
|
||||
/**
|
||||
* 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
|
||||
* inside the set
|
||||
*/
|
||||
class AuditCategory extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "application",
|
||||
"name" => "AuditCategory",
|
||||
"description" => "A section inside the overall audit",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array('name'),
|
||||
"db_table" => "priv_auditcategory",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../application/templates/audit_category.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Category Name", "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("description", array("label"=>"Audit Category Description", "description"=>"Long description for this audit category", "allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("definition_set", array("label"=>"Definition Set", "description"=>"SibusQL expression defining the set of objects to audit", "allowed_values"=>null, "sql"=>"definition_set", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("description");
|
||||
MetaModel::Init_AddFilterFromAttribute("definition_set");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'definition_set')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'description', )); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'description')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'description', 'definition_set')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
?>
|
||||
52
application/audit.rule.class.inc.php
Normal file
52
application/audit.rule.class.inc.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
require_once('../application/audit.category.class.inc.php');
|
||||
|
||||
/**
|
||||
* This class manages the audit "rule" linked to a given audit category.
|
||||
* Each rule is based ona SibusQL expression that returns either the "good" objects
|
||||
* or the "bad" ones. The core audit engines computes the complement to the definition
|
||||
* set when needed to obtain either the valid objects, or the ones with an error
|
||||
*/
|
||||
class AuditRule extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "application",
|
||||
"name" => "AuditRule",
|
||||
"description" => "A rule to check for a given Audit category",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array('name'),
|
||||
"db_table" => "priv_auditrule",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Rule Name", "description"=>"Short name for this rule", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("label"=>"Audit Rule Description", "description"=>"Long description for this audit rule", "allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("query", array("label"=>"Query to Run", "description"=>"The SibusQL expression to run", "allowed_values"=>null, "sql"=>"query", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("valid_flag", array("label"=>"Valid objects?", "description"=>"True if the rule returns the valid objects, false otherwise", "allowed_values"=>new ValueSetEnum('true,false'), "sql"=>"valid_flag", "default_value"=>"true", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("label"=>"Category", "description"=>"The category for this rule", "allowed_values"=>null, "sql"=>"category_id", "targetclass"=>"AuditCategory", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", array("label"=>"Category", "description"=>"Name of the category for this rule", "allowed_values"=>null, "extkey_attcode"=> 'category_id', "target_attcode"=>"name")));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("description");
|
||||
MetaModel::Init_AddFilterFromAttribute("query");
|
||||
MetaModel::Init_AddFilterFromAttribute("valid_flag");
|
||||
MetaModel::Init_AddFilterFromAttribute("category_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("category_name");
|
||||
|
||||
// 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('list', array('category_id', 'name', 'description', 'valid_flag')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('category_id', 'name', 'description', 'valid_flag')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('category_id', 'name', 'description', 'valid_flag', 'query')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
?>
|
||||
899
application/cmdbabstract.class.inc.php
Normal file
899
application/cmdbabstract.class.inc.php
Normal file
@@ -0,0 +1,899 @@
|
||||
<?php
|
||||
require_once('../core/cmdbobject.class.inc.php');
|
||||
require_once('../application/utils.inc.php');
|
||||
require_once('../application/applicationcontext.class.inc.php');
|
||||
require_once('../application/ui.linkswidget.class.inc.php');
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Abstract class that implements some common and useful methods for displaying
|
||||
* the objects
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
abstract class cmdbAbstractObject extends CMDBObject
|
||||
{
|
||||
|
||||
public static function GetUIPage()
|
||||
{
|
||||
return '../pages/UI.php';
|
||||
}
|
||||
|
||||
public static function ComputeUIPage($sClass)
|
||||
{
|
||||
static $aUIPagesCache = array(); // Cache to store the php page used to display each class of object
|
||||
if (!isset($aUIPagesCache[$sClass]))
|
||||
{
|
||||
$UIPage = false;
|
||||
if (is_callable("$sClass::GetUIPage"))
|
||||
{
|
||||
$UIPage = eval("return $sClass::GetUIPage();"); // May return false in case of error
|
||||
}
|
||||
$aUIPagesCache[$sClass] = $UIPage === false ? './UI.php' : $UIPage;
|
||||
}
|
||||
$sPage = $aUIPagesCache[$sClass];
|
||||
return $sPage;
|
||||
}
|
||||
|
||||
protected static function MakeHyperLink($sObjClass, $sObjKey, $aAvailableFields)
|
||||
{
|
||||
if ($sObjKey <= 0) return '<em>undefined</em>'; // Objects built in memory have negative IDs
|
||||
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sExtClassNameAtt = MetaModel::GetNameAttributeCode($sObjClass);
|
||||
$sPage = self::ComputeUIPage($sObjClass);
|
||||
$sAbsoluteUrl = utils::GetAbsoluteUrl(false); // False => Don't get the query string
|
||||
$sAbsoluteUrl = substr($sAbsoluteUrl, 0, 1+strrpos($sAbsoluteUrl, '/')); // remove the current page, keep just the path, up to the last /
|
||||
|
||||
// Use the "name" of the target class as the label of the hyperlink
|
||||
// unless it's not available in the external attributes...
|
||||
if (isset($aAvailableFields[$sExtClassNameAtt]))
|
||||
{
|
||||
$sLabel = $aAvailableFields[$sExtClassNameAtt];
|
||||
}
|
||||
else
|
||||
{
|
||||
$sLabel = implode(' / ', $aAvailableFields);
|
||||
}
|
||||
// Safety belt
|
||||
//
|
||||
if (empty($sLabel))
|
||||
{
|
||||
// Developer's note:
|
||||
// This is doing the job for you, but that is just there in case
|
||||
// the external fields associated to the external key are blanks
|
||||
// The ultimate solution will be to query the name automatically
|
||||
// and independantly from the data model (automatic external field)
|
||||
// AND make the name be a mandatory field
|
||||
//
|
||||
$sObject = MetaModel::GetObject($sObjClass, $sObjKey);
|
||||
$sLabel = $sObject->GetDisplayName();
|
||||
}
|
||||
// Safety net
|
||||
//
|
||||
if (empty($sLabel))
|
||||
{
|
||||
$sLabel = MetaModel::GetName($sObjClass)." #$sObjKey";
|
||||
}
|
||||
$sHint = MetaModel::GetName($sObjClass)."::$sObjKey";
|
||||
return "<a href=\"{$sAbsoluteUrl}{$sPage}?operation=details&class=$sObjClass&id=$sObjKey&".$oAppContext->GetForLink()."\" title=\"$sHint\">$sLabel</a>";
|
||||
}
|
||||
|
||||
public function GetDisplayValue($sAttCode)
|
||||
{
|
||||
$sDisplayValue = "";
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode(get_class($this));
|
||||
if ($sStateAttCode == $sAttCode)
|
||||
{
|
||||
$aStates = MetaModel::EnumStates(get_class($this));
|
||||
$sDisplayValue = $aStates[$this->Get($sAttCode)]['label'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$oAtt = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
|
||||
|
||||
if ($oAtt->IsExternalKey())
|
||||
{
|
||||
$sTargetClass = $oAtt->GetTargetClass();
|
||||
if ($this->IsNew())
|
||||
{
|
||||
// The current object exists only in memory, don't try to query it in the DB !
|
||||
// instead let's query for the object pointed by the external key, and get its name
|
||||
$targetObjId = $this->Get($sAttCode);
|
||||
$oTargetObj = MetaModel::GetObject($sTargetClass, $targetObjId, false); // false => not sure it exists
|
||||
if (is_object($oTargetObj))
|
||||
{
|
||||
$sDisplayValue = $oTargetObj->GetName();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// retrieve the "external fields" linked to this external key
|
||||
foreach (MetaModel::GetExternalFields(get_class($this), $sAttCode) as $oExtField)
|
||||
{
|
||||
$aAvailableFields[$oExtField->GetExtAttCode()] = $oExtField->GetAsHTML($this->Get($oExtField->GetCode()));
|
||||
}
|
||||
// Use the "name" of the target class as the label of the hyperlink
|
||||
// unless it's not available in the external fields...
|
||||
$sExtClassNameAtt = MetaModel::GetNameAttributeCode($sTargetClass);
|
||||
if (isset($aAvailableFields[$sExtClassNameAtt]))
|
||||
{
|
||||
$sDisplayValue = $aAvailableFields[$sExtClassNameAtt];
|
||||
}
|
||||
else
|
||||
{
|
||||
$sDisplayValue = implode(' / ', $aAvailableFields);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sDisplayValue = $this->GetAsHTML($sAttCode);
|
||||
}
|
||||
}
|
||||
return $sDisplayValue;
|
||||
}
|
||||
|
||||
function DisplayBareHeader(WebPage $oPage)
|
||||
{
|
||||
// Standard Header with name, actions menu and history block
|
||||
//
|
||||
$oPage->add("<div class=\"page_header\">\n");
|
||||
|
||||
// action menu
|
||||
$oSingletonFilter = new DBObjectSearch(get_class($this));
|
||||
$oSingletonFilter->AddCondition('pkey', array($this->GetKey()));
|
||||
$oBlock = new MenuBlock($oSingletonFilter, 'popup', false);
|
||||
$oBlock->Display($oPage, -1);
|
||||
|
||||
$oPage->add("<h1>".MetaModel::GetName(get_class($this)).": <span class=\"hilite\">".$this->GetDisplayName()."</span></h1>\n");
|
||||
|
||||
// history block (with toggle)
|
||||
$oHistoryFilter = new DBObjectSearch('CMDBChangeOp');
|
||||
$oHistoryFilter->AddCondition('objkey', $this->GetKey());
|
||||
$oHistoryFilter->AddCondition('objclass', get_class($this));
|
||||
$oBlock = new HistoryBlock($oHistoryFilter, 'toggle', false);
|
||||
$oBlock->Display($oPage, -1);
|
||||
|
||||
$oPage->add("</div>\n");
|
||||
}
|
||||
|
||||
function DisplayBareDetails(WebPage $oPage)
|
||||
{
|
||||
$oPage->add($this->GetBareDetails($oPage));
|
||||
}
|
||||
|
||||
function DisplayBareRelations(WebPage $oPage)
|
||||
{
|
||||
// Related objects
|
||||
$oPage->AddTabContainer('Related Objects');
|
||||
$oPage->SetCurrentTabContainer('Related Objects');
|
||||
foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sAttCode=>$oAttDef)
|
||||
{
|
||||
if ((get_class($oAttDef) == 'AttributeLinkedSetIndirect') || (get_class($oAttDef) == 'AttributeLinkedSet'))
|
||||
{
|
||||
$oPage->SetCurrentTab($oAttDef->GetLabel());
|
||||
$oPage->p($oAttDef->GetDescription());
|
||||
|
||||
if (get_class($oAttDef) == 'AttributeLinkedSet')
|
||||
{
|
||||
$sTargetClass = $oAttDef->GetLinkedClass();
|
||||
$oFilter = new DBObjectSearch($sTargetClass);
|
||||
$oFilter->AddCondition($oAttDef->GetExtKeyToMe(), $this->GetKey()); // @@@ condition has same name as field ??
|
||||
|
||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
$oBlock->Display($oPage, 0);
|
||||
}
|
||||
else // get_class($oAttDef) == 'AttributeLinkedSetIndirect'
|
||||
{
|
||||
$sLinkClass = $oAttDef->GetLinkedClass();
|
||||
// Transform the DBObjectSet into a CMBDObjectSet !!!
|
||||
$aLinkedObjects = $this->Get($sAttCode)->ToArray(false);
|
||||
if (count($aLinkedObjects) > 0)
|
||||
{
|
||||
$oSet = CMDBObjectSet::FromArray($sLinkClass, $aLinkedObjects);
|
||||
$aParams = array(
|
||||
'link_attr' => $oAttDef->GetExtKeyToMe(),
|
||||
'object_id' => $this->GetKey(),
|
||||
'target_attr' => $oAttDef->GetExtKeyToRemote(),
|
||||
);
|
||||
self::DisplaySet($oPage, $oSet, $aParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$oPage->SetCurrentTab('');
|
||||
}
|
||||
|
||||
function GetDisplayName()
|
||||
{
|
||||
$sDisplayName = '';
|
||||
if (MetaModel::GetNameAttributeCode(get_class($this)) != '')
|
||||
{
|
||||
$sDisplayName = $this->GetAsHTML(MetaModel::GetNameAttributeCode(get_class($this)));
|
||||
}
|
||||
return $sDisplayName;
|
||||
}
|
||||
|
||||
function GetBareDetails(WebPage $oPage)
|
||||
{
|
||||
$sHtml = '';
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode(get_class($this));
|
||||
$aDetails = array();
|
||||
$sClass = get_class($this);
|
||||
$aList = MetaModel::GetZListItems($sClass, 'details');
|
||||
|
||||
foreach($aList as $sAttCode)
|
||||
{
|
||||
$iFlags = $this->GetAttributeFlags($sAttCode);
|
||||
if ( ($iFlags & OPT_ATT_HIDDEN) == 0)
|
||||
{
|
||||
// The field is visible in the current state of the object
|
||||
if ($sStateAttCode == $sAttCode)
|
||||
{
|
||||
// Special display for the 'state' attribute itself
|
||||
$sDisplayValue = $this->GetState();
|
||||
}
|
||||
else
|
||||
{
|
||||
$sDisplayValue = $this->GetAsHTML($sAttCode);
|
||||
}
|
||||
$aDetails[] = array('label' => MetaModel::GetLabel($sClass, $sAttCode), 'value' => $sDisplayValue);
|
||||
}
|
||||
}
|
||||
$sHtml .= $oPage->GetDetails($aDetails);
|
||||
// Documents displayed inline (when possible: images, html...)
|
||||
foreach($aList as $sAttCode)
|
||||
{
|
||||
$oAttDef = Metamodel::GetAttributeDef($sClass, $sAttCode);
|
||||
if ( $oAttDef->GetEditClass() == 'Document')
|
||||
{
|
||||
$oDoc = $this->Get($sAttCode);
|
||||
if (is_object($oDoc) && !$oDoc->IsEmpty())
|
||||
{
|
||||
$sHtml .= "<p>Open in New Window: ".$oDoc->GetDisplayLink($sClass, $this->GetKey(), $sAttCode).", \n";
|
||||
$sHtml .= "Download: ".$oDoc->GetDownloadLink($sClass, $this->GetKey(), $sAttCode)."</p>\n";
|
||||
$sHtml .= "<div>".$oDoc->GetDisplayInline($sClass, $this->GetKey(), $sAttCode)."</div>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
|
||||
function DisplayDetails(WebPage $oPage)
|
||||
{
|
||||
$sTemplate = Utils::ReadFromFile(MetaModel::GetDisplayTemplate(get_class($this)));
|
||||
if (!empty($sTemplate))
|
||||
{
|
||||
$oTemplate = new DisplayTemplate($sTemplate);
|
||||
$oTemplate->Render($oPage, array('class_name'=> MetaModel::GetName(get_class($this)),'class'=> get_class($this),'pkey'=> $this->GetKey(), 'name' => $this->GetName()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Object's details
|
||||
// template not found display the object using the *old style*
|
||||
$this->DisplayBareHeader($oPage);
|
||||
$this->DisplayBareDetails($oPage);
|
||||
$this->DisplayBareRelations($oPage);
|
||||
}
|
||||
}
|
||||
|
||||
function DisplayPreview(WebPage $oPage)
|
||||
{
|
||||
$aDetails = array();
|
||||
$sClass = get_class($this);
|
||||
$aList = MetaModel::GetZListItems($sClass, 'preview');
|
||||
foreach($aList as $sAttCode)
|
||||
{
|
||||
$aDetails[] = array('label' => MetaModel::GetLabel($sClass, $sAttCode), 'value' =>$this->GetAsHTML($sAttCode));
|
||||
}
|
||||
$oPage->details($aDetails);
|
||||
}
|
||||
|
||||
// Comment by Rom: this helper may be used to display objects of class DBObject
|
||||
// -> I am using this to display the changes history
|
||||
public static function DisplaySet(WebPage $oPage, CMDBObjectSet $oSet, $aExtraParams = array())
|
||||
{
|
||||
$oPage->add(self::GetDisplaySet($oPage, $oSet, $aExtraParams));
|
||||
}
|
||||
|
||||
//public static function GetDisplaySet(WebPage $oPage, CMDBObjectSet $oSet, $sLinkageAttribute = '', $bDisplayMenu = true, $bSelectMode = false)
|
||||
public static function GetDisplaySet(WebPage $oPage, CMDBObjectSet $oSet, $aExtraParams = array())
|
||||
{
|
||||
static $iListId = 0;
|
||||
$iListId++;
|
||||
|
||||
// Initialize and check the parameters
|
||||
$sLinkageAttribute = isset($aExtraParams['link_attr']) ? $aExtraParams['link_attr'] : '';
|
||||
$iLinkedObjectId = isset($aExtraParams['object_id']) ? $aExtraParams['object_id'] : 0;
|
||||
$sTargetAttr = isset($aExtraParams['target_attr']) ? $aExtraParams['target_attr'] : '';
|
||||
if (!empty($sLinkageAttribute))
|
||||
{
|
||||
if($iLinkedObjectId == 0)
|
||||
{
|
||||
// if 'links' mode is requested the id of the object to link to must be specified
|
||||
throw new ApplicationException("Parameter object_id is mandatory when link_attr is specified. Check the definition of the display template.");
|
||||
}
|
||||
if($sTargetAttr == '')
|
||||
{
|
||||
// if 'links' mode is requested the d of the object to link to must be specified
|
||||
throw new ApplicationException("Parameter target_attr is mandatory when link_attr is specified. Check the definition of the display template.");
|
||||
}
|
||||
}
|
||||
$bDisplayMenu = isset($aExtraParams['menu']) ? $aExtraParams['menu'] == true : true;
|
||||
$bSelectMode = isset($aExtraParams['selection_mode']) ? $aExtraParams['selection_mode'] == true : false;
|
||||
|
||||
$sHtml = '';
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sClassName = $oSet->GetFilter()->GetClass();
|
||||
$aAttribs = array();
|
||||
$aList = MetaModel::GetZListItems($sClassName, 'list');
|
||||
if (!empty($sLinkageAttribute))
|
||||
{
|
||||
// The set to display is in fact a set of links between the object specified in the $sLinkageAttribute
|
||||
// and other objects...
|
||||
// The display will then group all the attributes related to the link itself:
|
||||
// | Link_attr1 | link_attr2 | ... || Object_attr1 | Object_attr2 | Object_attr3 | .. | Object_attr_n |
|
||||
$aAttDefs = MetaModel::ListAttributeDefs($sClassName);
|
||||
assert(isset($aAttDefs[$sLinkageAttribute]));
|
||||
$oAttDef = $aAttDefs[$sLinkageAttribute];
|
||||
assert($oAttDef->IsExternalKey());
|
||||
// First display all the attributes specific to the link record
|
||||
foreach($aList as $sLinkAttCode)
|
||||
{
|
||||
$oLinkAttDef = $aAttDefs[$sLinkAttCode];
|
||||
if ( (!$oLinkAttDef->IsExternalKey()) && (!$oLinkAttDef->IsExternalField()) )
|
||||
{
|
||||
$aDisplayList[] = $sLinkAttCode;
|
||||
}
|
||||
}
|
||||
// Then display all the attributes neither specific to the link record nor to the 'linkage' object (because the latter are constant)
|
||||
foreach($aList as $sLinkAttCode)
|
||||
{
|
||||
$oLinkAttDef = $aAttDefs[$sLinkAttCode];
|
||||
if (($oLinkAttDef->IsExternalKey() && ($sLinkAttCode != $sLinkageAttribute))
|
||||
|| ($oLinkAttDef->IsExternalField() && ($oLinkAttDef->GetKeyAttCode()!=$sLinkageAttribute)) )
|
||||
{
|
||||
$aDisplayList[] = $sLinkAttCode;
|
||||
}
|
||||
}
|
||||
// First display all the attributes specific to the link
|
||||
// Then display all the attributes linked to the other end of the relationship
|
||||
$aList = $aDisplayList;
|
||||
}
|
||||
if ($bSelectMode)
|
||||
{
|
||||
$aAttribs['form::select'] = array('label' => "<input type=\"checkbox\" onChange=\"var value = this.checked; $('.selectList{$iListId}').each( function() { this.checked = value; } );\"></input>", 'description' => 'Select / Deselect All');
|
||||
}
|
||||
$aAttribs['key'] = array('label' => '', 'description' => 'Click to display');
|
||||
foreach($aList as $sAttCode)
|
||||
{
|
||||
$aAttribs[$sAttCode] = array('label' => MetaModel::GetLabel($sClassName, $sAttCode), 'description' => MetaModel::GetDescription($sClassName, $sAttCode));
|
||||
}
|
||||
$aValues = array();
|
||||
$oSet->Seek(0);
|
||||
$bDisplayLimit = isset($aExtraParams['display_limit']) ? $aExtraParams['display_limit'] : true;
|
||||
$iMaxObjects = -1;
|
||||
if ($bDisplayLimit)
|
||||
{
|
||||
if ($oSet->Count() > utils::GetConfig()->GetMaxDisplayLimit())
|
||||
{
|
||||
$iMaxObjects = utils::GetConfig()->GetMinDisplayLimit();
|
||||
}
|
||||
}
|
||||
while (($oObj = $oSet->Fetch()) && ($iMaxObjects != 0))
|
||||
{
|
||||
$aRow = array();
|
||||
$aRow['key'] = $oObj->GetKey();
|
||||
if ($bSelectMode)
|
||||
{
|
||||
$aRow['form::select'] = "<input type=\"checkBox\" class=\"selectList{$iListId}\" name=\"selectObject[]\" value=\"".$oObj->GetKey()."\"></input>";
|
||||
}
|
||||
$aRow['key'] = $oObj->GetKey();
|
||||
foreach($aList as $sAttCode)
|
||||
{
|
||||
$aRow[$sAttCode] = $oObj->GetAsHTML($sAttCode);
|
||||
}
|
||||
$aValues[] = $aRow;
|
||||
$iMaxObjects--;
|
||||
}
|
||||
$oMenuBlock = new MenuBlock($oSet->GetFilter());
|
||||
$sHtml .= '<table class="listContainer">';
|
||||
$sColspan = '';
|
||||
if ($bDisplayMenu)
|
||||
{
|
||||
$sColspan = 'colspan="2"';
|
||||
$aMenuExtraParams = $aExtraParams;
|
||||
if (!empty($sLinkageAttribute))
|
||||
{
|
||||
//$aMenuExtraParams['linkage'] = $sLinkageAttribute;
|
||||
$aMenuExtraParams = $aExtraParams;
|
||||
}
|
||||
if ($bDisplayLimit && ($oSet->Count() > utils::GetConfig()->GetMaxDisplayLimit()))
|
||||
{
|
||||
// list truncated
|
||||
$divId = $aExtraParams['block_id'];
|
||||
$sFilter = $oSet->GetFilter()->serialize();
|
||||
$aExtraParams['display_limit'] = false; // To expand the full list
|
||||
$sExtraParams = addslashes(str_replace('"', "'", json_encode($aExtraParams))); // JSON encode, change the style of the quotes and escape them
|
||||
$sHtml .= '<tr class="containerHeader"><td>'.utils::GetConfig()->GetMinDisplayLimit().' object(s) displayed out of '.$oSet->Count().' <a href="Javascript:ReloadTruncatedList(\''.$divId.'\', \''.$sFilter.'\', \''.$sExtraParams.'\');">Display All</a></td><td>';
|
||||
$oPage->add_ready_script("$('#{$divId} table.listResults').addClass('truncated');");
|
||||
$oPage->add_ready_script("$('#{$divId} table.listResults tr:last td').addClass('truncated');");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Full list
|
||||
$sHtml .= '<tr class="containerHeader"><td> '.$oSet->Count().' object(s)</td><td>';
|
||||
}
|
||||
$sHtml .= $oMenuBlock->GetRenderContent($oPage, $aMenuExtraParams);
|
||||
$sHtml .= '</td></tr>';
|
||||
}
|
||||
$sHtml .= "<tr><td $sColspan>";
|
||||
$sHtml .= $oPage->GetTable($aAttribs, $aValues, array('class'=>$sClassName, 'filter'=>$oSet->GetFilter()->serialize(), 'preview' => true));
|
||||
$sHtml .= '</td></tr>';
|
||||
$sHtml .= '</table>';
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
static function DisplaySetAsCSV(WebPage $oPage, CMDBObjectSet $oSet, $aParams = array())
|
||||
{
|
||||
$oPage->add(self::GetSetAsCSV($oSet, $aParams));
|
||||
}
|
||||
|
||||
static function GetSetAsCSV(DBObjectSet $oSet, $aParams = array())
|
||||
{
|
||||
$sSeparator = isset($aParams['separator']) ? $aParams['separator'] : ','; // default separator is comma
|
||||
$sTextQualifier = isset($aParams['text_qualifier']) ? $aParams['text_qualifier'] : '"'; // default text qualifier is double quote
|
||||
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sClassName = $oSet->GetFilter()->GetClass();
|
||||
$aAttribs = array();
|
||||
$aList = MetaModel::GetZListItems($sClassName, 'details');
|
||||
$aHeader = array();
|
||||
$aHeader[] = MetaModel::GetKeyLabel($sClassName);
|
||||
foreach($aList as $sAttCode)
|
||||
{
|
||||
$aHeader[] = MetaModel::GetLabel($sClassName, $sAttCode);
|
||||
}
|
||||
$sHtml = '#'.$oSet->GetFilter()->ToOQL()."\n";
|
||||
$sHtml .= implode($sSeparator, $aHeader)."\n";
|
||||
$oSet->Seek(0);
|
||||
while ($oObj = $oSet->Fetch())
|
||||
{
|
||||
$aRow = array();
|
||||
$aRow[] = $oObj->GetKey();
|
||||
foreach($aList as $sAttCode)
|
||||
{
|
||||
$aRow[] = $oObj->GetAsCSV($sAttCode, $sSeparator, '\\');
|
||||
}
|
||||
$sHtml .= implode($sSeparator, $aRow)."\n";
|
||||
}
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
static function DisplaySetAsXML(WebPage $oPage, CMDBObjectSet $oSet, $aParams = array())
|
||||
{
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sClassName = $oSet->GetFilter()->GetClass();
|
||||
$aAttribs = array();
|
||||
$aList = MetaModel::GetZListItems($sClassName, 'details');
|
||||
$oPage->add("<Set>\n");
|
||||
$oSet->Seek(0);
|
||||
while ($oObj = $oSet->Fetch())
|
||||
{
|
||||
$sClassName = get_class($oObj);
|
||||
$oPage->add("<$sClassName id=\"".$oObj->GetKey()."\">\n");
|
||||
foreach(MetaModel::ListAttributeDefs($sClassName) as $sAttCode=>$oAttDef)
|
||||
{
|
||||
if (($oAttDef->IsWritable()) && ($oAttDef->IsScalar()) && ($sAttCode != 'finalclass') )
|
||||
{
|
||||
$sValue = $oObj->GetAsXML($sAttCode);
|
||||
$oPage->add("<$sAttCode>$sValue</$sAttCode>\n");
|
||||
}
|
||||
}
|
||||
$oPage->add("</$sClassName>\n");
|
||||
}
|
||||
$oPage->add("</Set>\n");
|
||||
}
|
||||
|
||||
// By rom
|
||||
function DisplayChangesLog(WebPage $oPage)
|
||||
{
|
||||
$oFltChangeOps = new CMDBSearchFilter('CMDBChangeOpSetAttribute');
|
||||
$oFltChangeOps->AddCondition('objkey', $this->GetKey(), '=');
|
||||
$oFltChangeOps->AddCondition('objclass', get_class($this), '=');
|
||||
$oSet = new CMDBObjectSet($oFltChangeOps, array('date' => false)); // order by date descending (i.e. false)
|
||||
$count = $oSet->Count();
|
||||
if ($count > 0)
|
||||
{
|
||||
$oPage->p("Changes log ($count):");
|
||||
self::DisplaySet($oPage, $oSet);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oPage->p("Changes log is empty");
|
||||
}
|
||||
}
|
||||
|
||||
public static function DisplaySearchForm(WebPage $oPage, CMDBObjectSet $oSet, $aExtraParams = array())
|
||||
{
|
||||
|
||||
$oPage->add(self::GetSearchForm($oPage, $oSet, $aExtraParams));
|
||||
}
|
||||
|
||||
public static function GetSearchForm(WebPage $oPage, CMDBObjectSet $oSet, $aExtraParams = array())
|
||||
{
|
||||
static $iSearchFormId = 0;
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sHtml = '';
|
||||
$numCols=4;
|
||||
$iSearchFormId++;
|
||||
$sClassName = $oSet->GetFilter()->GetClass();
|
||||
|
||||
// Romain: temporarily removed the tab "OQL query" because it was not finalized
|
||||
// (especially when used to add a link)
|
||||
/*
|
||||
$sHtml .= "<div class=\"mini_tabs\" id=\"mini_tabs{$iSearchFormId}\"><ul>
|
||||
<li><a href=\"#\" onClick=\"$('div.mini_tab{$iSearchFormId}').toggle();$('#mini_tabs{$iSearchFormId} ul li a').toggleClass('selected');\">OQL Query</a></li>
|
||||
<li><a class=\"selected\" href=\"#\" onClick=\"$('div.mini_tab{$iSearchFormId}').toggle();$('#mini_tabs{$iSearchFormId} ul li a').toggleClass('selected');\">Simple Search</a></li>
|
||||
</ul></div>\n";
|
||||
*/
|
||||
// Simple search form
|
||||
$sHtml .= "<div id=\"SimpleSearchForm{$iSearchFormId}\" class=\"mini_tab{$iSearchFormId}\">\n";
|
||||
$sHtml .= "<h1>Search for ".MetaModel::GetName($sClassName)." Objects</h1>\n";
|
||||
$oUnlimitedFilter = new DBObjectSearch($sClassName);
|
||||
$sHtml .= "<form id=\"form{$iSearchFormId}\">\n";
|
||||
$index = 0;
|
||||
$sHtml .= "<table>\n";
|
||||
$aFilterCriteria = $oSet->GetFilter()->GetCriteria();
|
||||
$aMapCriteria = array();
|
||||
foreach($aFilterCriteria as $aCriteria)
|
||||
{
|
||||
$aMapCriteria[$aCriteria['filtercode']][] = array('value' => $aCriteria['value'], 'opcode' => $aCriteria['opcode']);
|
||||
}
|
||||
$aList = MetaModel::GetZListItems($sClassName, 'standard_search');
|
||||
foreach($aList as $sFilterCode)
|
||||
{
|
||||
$oAppContext->Reset($sFilterCode); // Make sure the same parameter will not be passed twice
|
||||
if (($index % $numCols) == 0)
|
||||
{
|
||||
if ($index != 0)
|
||||
{
|
||||
$sHtml .= "</tr>\n";
|
||||
}
|
||||
$sHtml .= "<tr>\n";
|
||||
}
|
||||
$sFilterValue = '';
|
||||
$sFilterValue = utils::ReadParam($sFilterCode, '');
|
||||
$sFilterOpCode = null; // Use the default 'loose' OpCode
|
||||
if (empty($sFilterValue))
|
||||
{
|
||||
if (isset($aMapCriteria[$sFilterCode]))
|
||||
{
|
||||
if (count($aMapCriteria[$sFilterCode]) > 1)
|
||||
{
|
||||
$sFilterValue = '* mixed *';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sFilterValue = $aMapCriteria[$sFilterCode][0]['value'];
|
||||
$sFilterOpCode = $aMapCriteria[$sFilterCode][0]['opcode'];
|
||||
}
|
||||
if ($sFilterCode != 'company')
|
||||
{
|
||||
$oUnlimitedFilter->AddCondition($sFilterCode, $sFilterValue, $sFilterOpCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
$aAllowedValues = MetaModel::GetAllowedValues_flt($sClassName, $sFilterCode, $aExtraParams);
|
||||
if ($aAllowedValues != null)
|
||||
{
|
||||
//Enum field or external key, display a combo
|
||||
$sValue = "<select name=\"$sFilterCode\">\n";
|
||||
$sValue .= "<option value=\"\">* Any *</option>\n";
|
||||
foreach($aAllowedValues as $key => $value)
|
||||
{
|
||||
if ($sFilterValue == $key)
|
||||
{
|
||||
$sSelected = ' selected';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSelected = '';
|
||||
}
|
||||
$sValue .= "<option value=\"$key\"$sSelected>$value</option>\n";
|
||||
}
|
||||
$sValue .= "</select>\n";
|
||||
$sHtml .= "<td><label>".MetaModel::GetFilterLabel($sClassName, $sFilterCode).":</label></td><td>$sValue</td>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Any value is possible, display an input box
|
||||
$sHtml .= "<td><label>".MetaModel::GetFilterLabel($sClassName, $sFilterCode).":</label></td><td><input class=\"textSearch\" name=\"$sFilterCode\" value=\"$sFilterValue\"/></td>\n";
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
if (($index % $numCols) != 0)
|
||||
{
|
||||
$sHtml .= "<td colspan=\"".(2*($numCols - ($index % $numCols)))."\"></td>\n";
|
||||
}
|
||||
$sHtml .= "</tr>\n";
|
||||
$sHtml .= "<tr><td colspan=\"".(2*$numCols)."\" align=\"right\"><input type=\"submit\" value=\" Search \"></td></tr>\n";
|
||||
$sHtml .= "</table>\n";
|
||||
foreach($aExtraParams as $sName => $sValue)
|
||||
{
|
||||
$sHtml .= "<input type=\"hidden\" name=\"$sName\" value=\"$sValue\" />\n";
|
||||
}
|
||||
$sHtml .= "<input type=\"hidden\" name=\"class\" value=\"$sClassName\" />\n";
|
||||
$sHtml .= "<input type=\"hidden\" name=\"dosearch\" value=\"1\" />\n";
|
||||
$sHtml .= "<input type=\"hidden\" name=\"operation\" value=\"search_form\" />\n";
|
||||
$sHtml .= $oAppContext->GetForForm();
|
||||
$sHtml .= "</form>\n";
|
||||
$sHtml .= "</div><!-- Simple search form -->\n";
|
||||
|
||||
// OQL query builder
|
||||
$sHtml .= "<div id=\"OQLQuery{$iSearchFormId}\" style=\"display:none\" class=\"mini_tab{$iSearchFormId}\">\n";
|
||||
$sHtml .= "<h1>OQL Query Builder</h1>\n";
|
||||
$sHtml .= "<form id=\"formOQL{$iSearchFormId}\"><table style=\"width:80%;\"><tr style=\"vertical-align:top\">\n";
|
||||
$sHtml .= "<td style=\"text-align:right\"><label>SELECT </label><select name=\"oql_class\">";
|
||||
$aClasses = MetaModel::EnumChildClasses($sClassName, ENUM_CHILD_CLASSES_ALL);
|
||||
$sSelectedClass = utils::ReadParam('oql_class', $sClassName);
|
||||
$sOQLClause = utils::ReadParam('oql_clause', '');
|
||||
asort($aClasses);
|
||||
foreach($aClasses as $sChildClass)
|
||||
{
|
||||
$sSelected = ($sChildClass == $sSelectedClass) ? 'selected' : '';
|
||||
$sHtml.= "<option value=\"$sChildClass\" $sSelected>".MetaModel::GetName($sChildClass)."</option>\n";
|
||||
}
|
||||
$sHtml .= "</select> </td><td>\n";
|
||||
$sHtml .= "<textarea name=\"oql_clause\" style=\"width:100%\">$sOQLClause</textarea></td></tr>\n";
|
||||
$sHtml .= "<tr><td colspan=\"2\" style=\"text-align:right\"><input type=\"submit\" value=\" Query \"></td></tr>\n";
|
||||
$sHtml .= "<input type=\"hidden\" name=\"dosearch\" value=\"1\" />\n";
|
||||
foreach($aExtraParams as $sName => $sValue)
|
||||
{
|
||||
$sHtml .= "<input type=\"hidden\" name=\"$sName\" value=\"$sValue\" />\n";
|
||||
}
|
||||
$sHtml .= "<input type=\"hidden\" name=\"operation\" value=\"search_oql\" />\n";
|
||||
$sHtml .= $oAppContext->GetForForm();
|
||||
$sHtml .= "</table></form>\n";
|
||||
$sHtml .= "</div><!-- OQL query form -->\n";
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
public static function GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $value = '', $sDisplayValue = '', $iId = '', $sNameSuffix = '', $iFlags = 0, $aArgs = array())
|
||||
{
|
||||
static $iInputId = 0;
|
||||
if (isset($aArgs[$sAttCode]) && empty($value))
|
||||
{
|
||||
// default value passed by the context (either the app context of the operation)
|
||||
$value = $aArgs[$sAttCode];
|
||||
}
|
||||
|
||||
if (!empty($iId))
|
||||
{
|
||||
$iInputId = $iId;
|
||||
}
|
||||
else
|
||||
{
|
||||
$iInputId++;
|
||||
}
|
||||
|
||||
if (!$oAttDef->IsExternalField())
|
||||
{
|
||||
$aCSSClasses = array();
|
||||
if ( (!$oAttDef->IsNullAllowed()) || ($iFlags & OPT_ATT_MANDATORY))
|
||||
{
|
||||
$aCSSClasses[] = 'mandatory';
|
||||
}
|
||||
$sCSSClasses = self::GetCSSClasses($aCSSClasses);
|
||||
switch($oAttDef->GetEditClass())
|
||||
{
|
||||
case 'Date':
|
||||
$aCSSClasses[] = 'date-pick';
|
||||
$sCSSClasses = self::GetCSSClasses($aCSSClasses);
|
||||
$sHTMLValue = "<input type=\"text\" size=\"20\" name=\"attr_{$sAttCode}{$sNameSuffix}\" value=\"$value\" id=\"$iInputId\"{$sCSSClasses}/>";
|
||||
break;
|
||||
|
||||
case 'Password':
|
||||
$sHTMLValue = "<input type=\"password\" size=\"30\" name=\"attr_{$sAttCode}{$sNameSuffix}\" value=\"$value\" id=\"$iInputId\"{$sCSSClasses}/>";
|
||||
break;
|
||||
|
||||
case 'Text':
|
||||
$sHTMLValue = "<textarea name=\"attr_{$sAttCode}{$sNameSuffix}\" rows=\"8\" cols=\"40\" id=\"$iInputId\"{$sCSSClasses}>$value</textarea>";
|
||||
break;
|
||||
|
||||
case 'List':
|
||||
$oWidget = new UILinksWidget($sClass, $sAttCode, $iInputId, $sNameSuffix);
|
||||
$sHTMLValue = $oWidget->Display($oPage, $value);
|
||||
break;
|
||||
|
||||
case 'Document':
|
||||
$oDocument = $value; // Value is an ormDocument object
|
||||
$sFileName = '';
|
||||
if (is_object($oDocument))
|
||||
{
|
||||
$sFileName = $oDocument->GetFileName();
|
||||
}
|
||||
$iMaxFileSize = utils::ConvertToBytes(ini_get('upload_max_filesize'));
|
||||
$sHTMLValue = "<input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"$iMaxFileSize\" />\n";
|
||||
$sHTMLValue .= "<input name=\"attr_{$sAttCode}{$sNameSuffix}\" type=\"hidden\" id=\"$iInputId\" \" value=\"$sFileName\"/>\n";
|
||||
$sHTMLValue .= "<span id=\"name_$iInputId\">$sFileName</span><br/>\n";
|
||||
$sHTMLValue .= "<input name=\"file_{$sAttCode}{$sNameSuffix}\" type=\"file\" id=\"file_$iInputId\" onChange=\"UpdateFileName('$iInputId', this.value);\"/>\n";
|
||||
break;
|
||||
|
||||
case 'String':
|
||||
default:
|
||||
// #@# todo - add context information (depending on dimensions)
|
||||
$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, $aArgs);
|
||||
if ($aAllowedValues !== null)
|
||||
{
|
||||
//Enum field or external key, display a combo
|
||||
//if (count($aAllowedValues) == 0)
|
||||
//{
|
||||
// $sHTMLValue = "<input count=\"0\" type=\"text\" size=\"30\" value=\"\" name=\"attr_{$sAttCode}{$sNameSuffix}\" id=\"$iInputId\"{$sCSSClasses}/>";
|
||||
//}
|
||||
//else if (count($aAllowedValues) > 50)
|
||||
if (count($aAllowedValues) > 50)
|
||||
{
|
||||
// too many choices, use an autocomplete
|
||||
// The input for the auto complete
|
||||
$sHTMLValue = "<input count=\"".count($aAllowedValues)."\" type=\"text\" id=\"label_$iInputId\" size=\"30\" value=\"$sDisplayValue\"{$sCSSClasses}/>";
|
||||
// another hidden input to store & pass the object's Id
|
||||
$sHTMLValue .= "<input type=\"hidden\" id=\"$iInputId\" name=\"attr_{$sAttCode}{$sNameSuffix}\" value=\"$value\" />\n";
|
||||
$oPage->add_ready_script("\$('#label_$iInputId').autocomplete('./ajax.render.php', { scroll:true, minChars:3, onItemSelect:selectItem, onFindValue:findValue, formatItem:formatItem, autoFill:true, keyHolder:'#$iInputId', extraParams:{operation:'autocomplete', sclass:'$sClass',attCode:'".$sAttCode."'}});");
|
||||
$oPage->add_ready_script("\$('#label_$iInputId').result( function(event, data, formatted) { if (data) { $('#{$iInputId}').val(data[1]); } } );");
|
||||
// Prepopulate with a default value -- but no display value...
|
||||
//if (!empty($value))
|
||||
//{
|
||||
// $oPage->add_ready_script("\$('#label_$iInputId').search( 'domino.combodo.com' );");
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Few choices, use a normal 'select'
|
||||
// In case there are no valid values, the select will be empty, thus blocking the user from validating the form
|
||||
$sHTMLValue = "<select name=\"attr_{$sAttCode}{$sNameSuffix}\" id=\"$iInputId\"{$sCSSClasses}>\n";
|
||||
$sHTMLValue .= "<option value=\"0\">-- select one --</option>\n";
|
||||
foreach($aAllowedValues as $key => $display_value)
|
||||
{
|
||||
$sSelected = ($value == $key) ? ' selected' : '';
|
||||
$sHTMLValue .= "<option value=\"$key\"$sSelected>$display_value</option>\n";
|
||||
}
|
||||
$sHTMLValue .= "</select>\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHTMLValue = "<input type=\"text\" size=\"30\" name=\"attr_{$sAttCode}{$sNameSuffix}\" value=\"$value\" id=\"$iInputId\"{$sCSSClasses} />";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $sHTMLValue;
|
||||
}
|
||||
|
||||
public function DisplayModifyForm(WebPage $oPage)
|
||||
{
|
||||
static $iFormId = 0;
|
||||
$iFormId++;
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode(get_class($this));
|
||||
$iKey = $this->GetKey();
|
||||
$aDetails = array();
|
||||
$oPage->add("<form id=\"form_{$iFormId}\" enctype=\"multipart/form-data\" method=\"post\" onSubmit=\"return CheckMandatoryFields('form_{$iFormId}')\">\n");
|
||||
foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sAttCode=>$oAttDef)
|
||||
{
|
||||
if ('finalclass' == $sAttCode) // finalclass is a reserved word, hardcoded !
|
||||
{
|
||||
// Do nothing, the class field is always hidden, it cannot be edited
|
||||
}
|
||||
else if ($sStateAttCode == $sAttCode)
|
||||
{
|
||||
// State attribute is always read-only from the UI
|
||||
$sHTMLValue = $this->GetState();
|
||||
$aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue);
|
||||
}
|
||||
else if (!$oAttDef->IsExternalField())
|
||||
{
|
||||
$iFlags = $this->GetAttributeFlags($sAttCode);
|
||||
if ($iFlags & OPT_ATT_HIDDEN)
|
||||
{
|
||||
// Attribute is hidden, do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($iFlags & OPT_ATT_READONLY)
|
||||
{
|
||||
// Attribute is read-only
|
||||
$sHTMLValue = $this->GetAsHTML($sAttCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sValue = $this->Get($sAttCode);
|
||||
$sDisplayValue = $this->GetDisplayValue($sAttCode);
|
||||
$aArgs = array('this' => $this);
|
||||
$sHTMLValue = self::GetFormElementForField($oPage, get_class($this), $sAttCode, $oAttDef, $sValue, $sDisplayValue, '', '', $iFlags, $aArgs);
|
||||
}
|
||||
$aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
$oPage->details($aDetails);
|
||||
$oPage->add("<input type=\"hidden\" name=\"id\" value=\"$iKey\">\n");
|
||||
$oPage->add("<input type=\"hidden\" name=\"class\" value=\"".get_class($this)."\">\n");
|
||||
$oPage->add("<input type=\"hidden\" name=\"operation\" value=\"apply_modify\">\n");
|
||||
$oPage->add("<input type=\"hidden\" name=\"transaction_id\" value=\"".utils::GetNewTransactionId()."\">\n");
|
||||
$oPage->add($oAppContext->GetForForm());
|
||||
$oPage->add("<button type=\"button\" class=\"action\" onClick=\"goBack()\"><span>Cancel</span></button> \n");
|
||||
$oPage->add("<button type=\"submit\" class=\"action\"><span>Apply</span></button>\n");
|
||||
$oPage->add("</form>\n");
|
||||
}
|
||||
|
||||
public static function DisplayCreationForm(WebPage $oPage, $sClass, $oObjectToClone = null, $aArgs = array())
|
||||
{
|
||||
static $iCreationFormId = 0;
|
||||
|
||||
$iCreationFormId++;
|
||||
$oAppContext = new ApplicationContext();
|
||||
$aDetails = array();
|
||||
$sOperation = ($oObjectToClone == null) ? 'apply_new' : 'apply_clone';
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode(get_class($oObjectToClone));
|
||||
$oPage->add("<form id=\"creation_form_{$iCreationFormId}\" method=\"post\" onSubmit=\"return CheckMandatoryFields('creation_form_{$iCreationFormId}')\">\n");
|
||||
$aStates = MetaModel::EnumStates($sClass);
|
||||
if ($oObjectToClone == null)
|
||||
{
|
||||
$sTargetState = MetaModel::GetDefaultState($sClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sTargetState = $oObjectToClone->GetState();
|
||||
}
|
||||
|
||||
foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode=>$oAttDef)
|
||||
{
|
||||
if ('finalclass' == $sAttCode) // finalclass is a reserved word, hardcoded !
|
||||
{
|
||||
// Do nothing, the class field is always hidden, it cannot be edited
|
||||
}
|
||||
else if ($sStateAttCode == $sAttCode)
|
||||
{
|
||||
// State attribute is always read-only from the UI
|
||||
$sHTMLValue = $oObjectToClone->GetState();
|
||||
$aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue);
|
||||
}
|
||||
else if (!$oAttDef->IsExternalField())
|
||||
{
|
||||
$sValue = ($oObjectToClone == null) ? '' : $oObjectToClone->Get($sAttCode);
|
||||
$sDisplayValue = ($oObjectToClone == null) ? '' : $oObjectToClone->GetDisplayValue($sAttCode);
|
||||
$iOptions = isset($aStates[$sTargetState]['attribute_list'][$sAttCode]) ? $aStates[$sTargetState]['attribute_list'][$sAttCode] : 0;
|
||||
|
||||
$sHTMLValue = self::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, '', '', $iOptions, $aArgs);
|
||||
$aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue);
|
||||
}
|
||||
}
|
||||
$oPage->details($aDetails);
|
||||
if ($oObjectToClone != null)
|
||||
{
|
||||
$oPage->add("<input type=\"hidden\" name=\"clone_id\" value=\"".$oObjectToClone->GetKey()."\">\n");
|
||||
}
|
||||
$oPage->add("<input type=\"hidden\" name=\"class\" value=\"$sClass\">\n");
|
||||
$oPage->add("<input type=\"hidden\" name=\"operation\" value=\"$sOperation\">\n");
|
||||
$oPage->add("<input type=\"hidden\" name=\"transaction_id\" value=\"".utils::GetNewTransactionId()."\">\n");
|
||||
$oPage->add($oAppContext->GetForForm());
|
||||
$oPage->add("<button type=\"button\" class=\"action\" onClick=\"goBack()\"><span>Cancel</span></button> \n");
|
||||
$oPage->add("<button type=\"submit\" class=\"action\"><span>Apply</span></button>\n");
|
||||
$oPage->add("</form>\n");
|
||||
}
|
||||
|
||||
protected static function GetCSSClasses($aCSSClasses)
|
||||
{
|
||||
$sCSSClasses = '';
|
||||
if (!empty($aCSSClasses))
|
||||
{
|
||||
$sCSSClasses = ' class="'.implode(' ', $aCSSClasses).'" ';
|
||||
}
|
||||
return $sCSSClasses;
|
||||
}
|
||||
}
|
||||
?>
|
||||
35
application/csvpage.class.inc.php
Normal file
35
application/csvpage.class.inc.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
require_once("../application/webpage.class.inc.php");
|
||||
/**
|
||||
* Simple web page with no includes or fancy formatting, useful to generateXML documents
|
||||
* The page adds the content-type text/XML and the encoding into the headers
|
||||
*/
|
||||
class CSVPage extends WebPage
|
||||
{
|
||||
function __construct($s_title)
|
||||
{
|
||||
parent::__construct($s_title);
|
||||
$this->add_header("Content-type: text/html; charset=iso-8859-1");
|
||||
$this->add_header("Cache-control: no-cache");
|
||||
}
|
||||
|
||||
public function output()
|
||||
{
|
||||
$this->add_header("Content-Length: ".strlen(trim($this->s_content)));
|
||||
foreach($this->a_headers as $s_header)
|
||||
{
|
||||
header($s_header);
|
||||
}
|
||||
echo trim($this->s_content);
|
||||
}
|
||||
|
||||
public function small_p($sText)
|
||||
{
|
||||
}
|
||||
|
||||
public function table($aConfig, $aData, $aParams = array())
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
252
application/dialogstack.class.inc.php
Normal file
252
application/dialogstack.class.inc.php
Normal file
@@ -0,0 +1,252 @@
|
||||
<?php
|
||||
/**
|
||||
* Helper class to allow modal-style dialog box in an html form
|
||||
*
|
||||
* Possible improvement: do not use _SESSION for the caller's data,
|
||||
* instead set a member variable with caller information
|
||||
* and take the opportunity of the first edit button to place the information
|
||||
* into a hidden field
|
||||
*
|
||||
* Usage:
|
||||
*/
|
||||
|
||||
define('DLGSTACK_OK', 1);
|
||||
define('DLGSTACK_CANCEL', 2);
|
||||
|
||||
//session_name("dialogstack");
|
||||
session_start();
|
||||
|
||||
|
||||
class dialogstack
|
||||
{
|
||||
private static $m_bCurrPageDeclared = false;
|
||||
/**
|
||||
* Declare the current page as being a dialog issuer, potentially pop...
|
||||
*/
|
||||
static public function DeclareCaller($sTitle)
|
||||
{
|
||||
self::$m_bCurrPageDeclared = false;
|
||||
$_SESSION['dialogstack_calleruri'] = $_SERVER["REQUEST_URI"];
|
||||
$_SESSION['dialogstack_callertitle'] = $sTitle;
|
||||
|
||||
if (isset($_POST["dialogstackpop"]) && ($_POST["dialogstackpop"] == count($_SESSION['dialogstack_currdlg'])))
|
||||
{
|
||||
// Pop !
|
||||
array_pop($_SESSION['dialogstack_currdlg']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the current page has been loaded from an "dialog startup button"
|
||||
*/
|
||||
static private function GetRetArgName()
|
||||
{
|
||||
foreach($_REQUEST as $sArgName=>$sArgValue)
|
||||
{
|
||||
if (strstr($sArgName, "dlgstack_go,"))
|
||||
{
|
||||
$aTokens = explode(",", $sArgName);
|
||||
return self::ArgNameDecode($aTokens[1]);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Protect against weird effects of PHP interpreting brackets...
|
||||
*/
|
||||
static private function ArgNameEncode($sArgName)
|
||||
{
|
||||
return str_replace(array('[', ']'), array('_bracket_open_', '_bracket_close_'), $sArgName);
|
||||
}
|
||||
static private function ArgNameDecode($sCodedArgName)
|
||||
{
|
||||
return str_replace(array('_bracket_open_', '_bracket_close_'), array('[', ']'), $sCodedArgName);
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the current page has been loaded from an "dialog startup button"
|
||||
*/
|
||||
static public function IsDialogStartup()
|
||||
{
|
||||
return (strlen(self::GetRetArgName()) > 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to
|
||||
*/
|
||||
static private function RemoveArg(&$aValues, $sKey, &$retval = null)
|
||||
{
|
||||
if (isset($aValues[$sKey]))
|
||||
{
|
||||
if (empty($retval))
|
||||
{
|
||||
$retval = $aValues[$sKey];
|
||||
}
|
||||
unset($aValues[$sKey]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Record current page args, and returns the initial value for the dialog
|
||||
*/
|
||||
static public function StartDialog()
|
||||
{
|
||||
if (!isset($_SESSION['dialogstack_currdlg']))
|
||||
{
|
||||
// Init stack
|
||||
$_SESSION['dialogstack_currdlg'] = array();
|
||||
}
|
||||
|
||||
$sRetArgName = self::GetRetArgName();
|
||||
$sCodedArgName = self::ArgNameEncode($sRetArgName);
|
||||
|
||||
$sArgForRetArgName = "dlgstack_init_".$sCodedArgName;
|
||||
$sButtonName = "dlgstack_go,".$sCodedArgName;
|
||||
|
||||
// Do not record utility arguments, neither the current value (stored separately)
|
||||
//
|
||||
$initValue = null;
|
||||
$aPost = $_POST;
|
||||
self::RemoveArg($aPost, $sArgForRetArgName, $initValue);
|
||||
self::RemoveArg($aPost, $sButtonName);
|
||||
self::RemoveArg($aPost, 'dlgstack_onok_page', $sOnOKPage);
|
||||
self::RemoveArg($aPost, 'dlgstack_onok_args', $aOnOKArgs);
|
||||
$aGet = $_GET;
|
||||
self::RemoveArg($aGet, $sArgForRetArgName, $initValue);
|
||||
self::RemoveArg($aGet, $sButtonName);
|
||||
self::RemoveArg($aGet, 'dlgstack_onok_page', $sOnOKPage);
|
||||
self::RemoveArg($aGet, 'dlgstack_onok_args', $aOnOKArgs);
|
||||
|
||||
if (self::$m_bCurrPageDeclared)
|
||||
{
|
||||
throw new Exception("DeclareCaller() must not be called before StartDialog()");
|
||||
}
|
||||
|
||||
$aCall = array(
|
||||
"title"=>$_SESSION['dialogstack_callertitle'],
|
||||
"uri"=>$_SESSION['dialogstack_calleruri'],
|
||||
"post"=>$aPost,
|
||||
"get"=>$aGet,
|
||||
"retarg"=>$sRetArgName,
|
||||
"initval"=>$initValue,
|
||||
);
|
||||
if (isset($sOnOKPage)) $aCall["onok_page"] = $sOnOKPage;
|
||||
if (isset($aOnOKArgs)) $aCall["onok_args"] = $aOnOKArgs;
|
||||
|
||||
array_push($_SESSION['dialogstack_currdlg'], $aCall);
|
||||
return $initValue;
|
||||
}
|
||||
/**
|
||||
* Render a button to launch a new dialog
|
||||
*/
|
||||
static public function RenderEditableField($sTitle, $sArgName, $sCurrValue, $bAddFieldValue, $sOnOKPage = "", $aOnOKArgs = array())
|
||||
{
|
||||
$sRet = "";
|
||||
$sCodedArgName = self::ArgNameEncode($sArgName);
|
||||
if ($bAddFieldValue)
|
||||
{
|
||||
$sRet .= "<input type=\"hidden\" name=\"$sArgName\" value=\"$sCurrValue\">\n";
|
||||
}
|
||||
$sRet .= "<input type=\"hidden\" name=\"dlgstack_init_$sCodedArgName\" value=\"$sCurrValue\">\n";
|
||||
$sRet .= "<input type=\"submit\" name=\"dlgstack_go,$sCodedArgName\" value=\"$sTitle\">\n";
|
||||
if (!empty($sOnOKPage))
|
||||
{
|
||||
$sRet .= "<input type=\"hidden\" name=\"dlgstack_onok_page\" value=\"$sCurrValue\">\n";
|
||||
}
|
||||
foreach($aOnOKArgs as $sArgName=>$value)
|
||||
{
|
||||
$sRet .= "<input type=\"hidden\" name=\"dlgstack_onok_args[$sArgName]\" value=\"$value\">\n";
|
||||
}
|
||||
return $sRet;
|
||||
}
|
||||
/**
|
||||
* Render a [set of] hidden field, from a value that may be an array
|
||||
*/
|
||||
static private function RenderHiddenField($sName, $value)
|
||||
{
|
||||
$sRet = "";
|
||||
if (is_array($value))
|
||||
{
|
||||
foreach($value as $sKey=>$subvalue)
|
||||
{
|
||||
$sRet .= self::RenderHiddenField($sName.'['.$sKey.']', $subvalue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sRet .= "<input type=\"hidden\" name=\"$sName\" value=\"$value\">\n";
|
||||
}
|
||||
return $sRet;
|
||||
}
|
||||
/**
|
||||
* Render a form to end the current dialog and return to the caller
|
||||
*/
|
||||
static public function RenderEndDialogForm($iButtonStyle, $sTitle, $sRetValue = null)
|
||||
{
|
||||
$aCall = end($_SESSION['dialogstack_currdlg']);
|
||||
if (!$aCall) return;
|
||||
return self::privRenderEndDialogForm($aCall, $iButtonStyle, $sTitle, $sRetValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of buttons to get back to upper dialog levels
|
||||
*/
|
||||
static public function GetCurrentStack()
|
||||
{
|
||||
$aRet = array();
|
||||
if (isset($_SESSION['dialogstack_currdlg']))
|
||||
{
|
||||
foreach ($_SESSION['dialogstack_currdlg'] as $aCall)
|
||||
{
|
||||
$aRet[] = self::privRenderEndDialogForm($aCall, DLGSTACK_CANCEL, $aCall["title"]);
|
||||
}
|
||||
}
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a form to end the current dialog and return to the caller
|
||||
*/
|
||||
static private function privRenderEndDialogForm($aCall, $iButtonStyle, $sTitle, $sRetValue = null)
|
||||
{
|
||||
if (($iButtonStyle == DLGSTACK_OK) && isset($aCall["onok_page"])) $sFormAction = $aCall["onok_page"];
|
||||
else $sFormAction = $aCall["uri"];
|
||||
|
||||
$sRet = "<form method=\"post\" action=\"$sFormAction\">\n";
|
||||
foreach ($aCall["post"] as $sName=>$value)
|
||||
{
|
||||
$sRet .= self::RenderHiddenField($sName, $value);
|
||||
}
|
||||
if ($iButtonStyle == DLGSTACK_OK)
|
||||
{
|
||||
if (isset($aCall["onok_args"]))
|
||||
{
|
||||
foreach($aCall["onok_args"] as $sArgName=>$value)
|
||||
{
|
||||
$sRet .= "<input type=\"hidden\" name=\"$sArgName\" value=\"$value\">\n";
|
||||
}
|
||||
}
|
||||
$sRet .= "<input type=\"hidden\" name=\"".$aCall["retarg"]."\" value=\"$sRetValue\">\n";
|
||||
$sRet .= "<input type=\"submit\" name=\"dlgstackOK\" value=\"$sTitle, (OK) Back to ".$aCall["title"]."\">\n";
|
||||
}
|
||||
elseif ($iButtonStyle == DLGSTACK_CANCEL)
|
||||
{
|
||||
if (!is_null($aCall["initval"]))
|
||||
{
|
||||
$sRet .= "<input type=\"hidden\" name=\"".$aCall["retarg"]."\" value=\"".$aCall["initval"]."\">\n";
|
||||
}
|
||||
$sRet .= "<input type=\"submit\" name=\"dlgstackCANCEL\" value=\"$sTitle\">\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Wrong value for button style ($iButtonStyle)");
|
||||
}
|
||||
$sRet .= "<input type=\"hidden\" name=\"dialogstackpop\" value=\"".count($_SESSION['dialogstack_currdlg'])."\">\n";
|
||||
$sRet .= "</form>\n";
|
||||
return $sRet;
|
||||
}
|
||||
}
|
||||
?>
|
||||
854
application/displayblock.class.inc.php
Normal file
854
application/displayblock.class.inc.php
Normal file
@@ -0,0 +1,854 @@
|
||||
<?php
|
||||
require_once('../application/webpage.class.inc.php');
|
||||
require_once('../application/utils.inc.php');
|
||||
require_once('../core/userrights.class.inc.php');
|
||||
/**
|
||||
* Helper class to manage 'blocks' of HTML pieces that are parts of a page and contain some list of cmdb objects
|
||||
*
|
||||
* Each block is actually rendered as a <div></div> tag that can be rendered synchronously
|
||||
* or as a piece of Javascript/JQuery/Ajax that will get its content from another page (ajax.render.php).
|
||||
* The list of cmdbObjects to be displayed into the block is defined by a filter
|
||||
* Right now the type of display is either: list, count, bare_details, details, csv, modify or search
|
||||
* - list produces a table listing the objects
|
||||
* - count produces a paragraphs with a sentence saying 'cont' objects found
|
||||
* - bare_details displays just the details of the attributes of the object (best if only one)
|
||||
* - details display the full details of each object found using its template (best if only one)
|
||||
* - csv displays a textarea with the CSV export of the list of objects
|
||||
* - modify displays the form to modify an object (best if only one)
|
||||
* - search displays a search form with the criteria of the filter set
|
||||
*/
|
||||
class DisplayBlock
|
||||
{
|
||||
const TAG_BLOCK = 'itopblock';
|
||||
protected $m_oFilter;
|
||||
protected $m_sStyle;
|
||||
protected $m_bAsynchronous;
|
||||
protected $m_aParams;
|
||||
protected $m_oSet;
|
||||
|
||||
public function __construct(DBObjectSearch $oFilter, $sStyle = 'list', $bAsynchronous = false, $aParams = array(), $oSet = null)
|
||||
{
|
||||
$this->m_oFilter = $oFilter;
|
||||
$this->m_sStyle = $sStyle;
|
||||
$this->m_bAsynchronous = $bAsynchronous;
|
||||
$this->m_aParams = $aParams;
|
||||
$this->m_oSet = $oSet;
|
||||
}
|
||||
/**
|
||||
* Constructs a DisplayBlock object from a DBObjectSet already in memory
|
||||
* @param $oSet DBObjectSet
|
||||
* @return DisplayBlock The DisplayBlock object, or null if the creation failed
|
||||
*/
|
||||
public static function FromObjectSet(DBObjectSet $oSet, $sStyle, $aParams = array())
|
||||
{
|
||||
$oDummyFilter = new DBObjectSearch($oSet->GetClass());
|
||||
$oBlock = new DisplayBlock($oDummyFilter, $sStyle, false, $aParams, $oSet); // DisplayBlocks built this way are synchronous
|
||||
return $oBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DisplayBlock object from an XML template
|
||||
* @param $sTemplate string The XML template
|
||||
* @return DisplayBlock The DisplayBlock object, or null if the template is invalid
|
||||
*/
|
||||
public static function FromTemplate($sTemplate)
|
||||
{
|
||||
$iStartPos = stripos($sTemplate, '<'.self::TAG_BLOCK.' ',0);
|
||||
$iEndPos = stripos($sTemplate, '</'.self::TAG_BLOCK.'>', $iStartPos);
|
||||
$iEndTag = stripos($sTemplate, '>', $iStartPos);
|
||||
$aParams = array();
|
||||
|
||||
if (($iStartPos === false) || ($iEndPos === false)) return null; // invalid template
|
||||
$sITopBlock = substr($sTemplate,$iStartPos, $iEndPos-$iStartPos+strlen('</'.self::TAG_BLOCK.'>'));
|
||||
$sITopData = substr($sTemplate, 1+$iEndTag, $iEndPos - $iEndTag - 1);
|
||||
$sITopTag = substr($sTemplate, $iStartPos + strlen('<'.self::TAG_BLOCK), $iEndTag - $iStartPos - strlen('<'.self::TAG_BLOCK));
|
||||
|
||||
$aMatches = array();
|
||||
$sBlockClass = "DisplayBlock";
|
||||
$bAsynchronous = false;
|
||||
$sBlockType = 'list';
|
||||
$sEncoding = 'text/serialize';
|
||||
if (preg_match('/ type="(.*)"/U',$sITopTag, $aMatches))
|
||||
{
|
||||
$sBlockType = strtolower($aMatches[1]);
|
||||
}
|
||||
if (preg_match('/ asynchronous="(.*)"/U',$sITopTag, $aMatches))
|
||||
{
|
||||
$bAsynchronous = (strtolower($aMatches[1]) == 'true');
|
||||
}
|
||||
if (preg_match('/ blockclass="(.*)"/U',$sITopTag, $aMatches))
|
||||
{
|
||||
$sBlockClass = $aMatches[1];
|
||||
}
|
||||
if (preg_match('/ objectclass="(.*)"/U',$sITopTag, $aMatches))
|
||||
{
|
||||
$sObjectClass = $aMatches[1];
|
||||
}
|
||||
if (preg_match('/ encoding="(.*)"/U',$sITopTag, $aMatches))
|
||||
{
|
||||
$sEncoding = strtolower($aMatches[1]);
|
||||
}
|
||||
if (preg_match('/ link_attr="(.*)"/U',$sITopTag, $aMatches))
|
||||
{
|
||||
// The list to display is a list of links to the specified object
|
||||
$aParams['link_attr'] = $aMatches[1]; // Name of the Ext. Key that makes this linkage
|
||||
}
|
||||
if (preg_match('/ target_attr="(.*)"/U',$sITopTag, $aMatches))
|
||||
{
|
||||
// The list to display is a list of links to the specified object
|
||||
$aParams['target_attr'] = $aMatches[1]; // Name of the Ext. Key that make this linkage
|
||||
}
|
||||
if (preg_match('/ object_id="(.*)"/U',$sITopTag, $aMatches))
|
||||
{
|
||||
// The list to display is a list of links to the specified object
|
||||
$aParams['object_id'] = $aMatches[1]; // Id of the object to be linked to
|
||||
}
|
||||
// Parameters contains a list of extra parameters for the block
|
||||
// the syntax is param_name1:value1;param_name2:value2;...
|
||||
if (preg_match('/ parameters="(.*)"/U',$sITopTag, $aMatches))
|
||||
{
|
||||
$sParameters = $aMatches[1];
|
||||
$aPairs = explode(';', $sParameters);
|
||||
foreach($aPairs as $sPair)
|
||||
{
|
||||
if (preg_match('/(.*)\:(.*)/',$sPair, $aMatches))
|
||||
{
|
||||
$aParams[trim($aMatches[1])] = trim($aMatches[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($aParams['link_attr']))
|
||||
{
|
||||
// Check that all mandatory parameters are present:
|
||||
if(empty($aParams['object_id']))
|
||||
{
|
||||
// if 'links' mode is requested the d of the object to link to must be specified
|
||||
throw new ApplicationException("Parameter object_id is mandatory when link_attr is specified. Check the definition of the display template.");
|
||||
}
|
||||
if(empty($aParams['target_attr']))
|
||||
{
|
||||
// if 'links' mode is requested the id of the object to link to must be specified
|
||||
throw new ApplicationException("Parameter target_attr is mandatory when link_attr is specified. Check the definition of the display template.");
|
||||
}
|
||||
|
||||
}
|
||||
switch($sEncoding)
|
||||
{
|
||||
case 'text/serialize':
|
||||
$oFilter = CMDBSearchFilter::unserialize($sITopData);
|
||||
break;
|
||||
|
||||
case 'text/sibusql':
|
||||
$oFilter = CMDBSearchFilter::FromSibusQL($sITopData);
|
||||
break;
|
||||
|
||||
case 'text/oql':
|
||||
$oFilter = CMDBSearchFilter::FromOQL($sITopData);
|
||||
break;
|
||||
}
|
||||
return new $sBlockClass($oFilter, $sBlockType, $bAsynchronous, $aParams);
|
||||
}
|
||||
|
||||
public function Display(WebPage $oPage, $sId, $aExtraParams = array())
|
||||
{
|
||||
$oPage->add($this->GetDisplay($oPage, $sId, $aExtraParams));
|
||||
/*
|
||||
$aExtraParams = array_merge($aExtraParams, $this->m_aParams);
|
||||
$aExtraParams['block_id'] = $sId;
|
||||
if (!$this->m_bAsynchronous)
|
||||
{
|
||||
// render now
|
||||
$oPage->add("<div id=\"$sId\" class=\"display_block\">\n");
|
||||
$this->RenderContent($oPage, $aExtraParams);
|
||||
$oPage->add("</div>\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// render it as an Ajax (asynchronous) call
|
||||
$sFilter = $this->m_oFilter->serialize();
|
||||
$oPage->add("<div id=\"$sId\" class=\"display_block loading\">\n");
|
||||
$oPage->p("<img src=\"../images/indicator_arrows.gif\"> Loading...");
|
||||
$oPage->add("</div>\n");
|
||||
$oPage->add('
|
||||
<script language="javascript">
|
||||
$.get("ajax.render.php?filter='.$sFilter.'&style='.$this->m_sStyle.'",
|
||||
{ operation: "ajax" },
|
||||
function(data){
|
||||
$("#'.$sId.'").empty();
|
||||
$("#'.$sId.'").append(data);
|
||||
$("#'.$sId.'").removeClass("loading");
|
||||
}
|
||||
);
|
||||
</script>'); // TO DO: add support for $aExtraParams in asynchronous/Ajax mode
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public function GetDisplay(WebPage $oPage, $sId, $aExtraParams = array())
|
||||
{
|
||||
$sHtml = '';
|
||||
$aExtraParams = array_merge($aExtraParams, $this->m_aParams);
|
||||
$aExtraParams['block_id'] = $sId;
|
||||
$sExtraParams = addslashes(str_replace('"', "'", json_encode($aExtraParams))); // JSON encode, change the style of the quotes and escape them
|
||||
|
||||
$bAutoReload = false;
|
||||
if (isset($aExtraParams['auto_reload']))
|
||||
{
|
||||
switch($aExtraParams['auto_reload'])
|
||||
{
|
||||
case 'fast':
|
||||
$bAutoReload = true;
|
||||
$iReloadInterval = utils::GetConfig()->GetFastReloadInterval()*1000;
|
||||
break;
|
||||
|
||||
case 'standard':
|
||||
case 'true':
|
||||
case true:
|
||||
$bAutoReload = true;
|
||||
$iReloadInterval = utils::GetConfig()->GetStandardReloadInterval()*1000;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (is_numeric($aExtraParams['auto_reload']))
|
||||
{
|
||||
$bAutoReload = true;
|
||||
$iReloadInterval = $aExtraParams['auto_reload']*1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
// incorrect config, ignore it
|
||||
$bAutoReload = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sFilter = $this->m_oFilter->serialize(); // Used either for asynchronous or auto_reload
|
||||
if (!$this->m_bAsynchronous)
|
||||
{
|
||||
// render now
|
||||
$sHtml .= "<div id=\"$sId\" class=\"display_block\">\n";
|
||||
$sHtml .= $this->GetRenderContent($oPage, $aExtraParams);
|
||||
$sHtml .= "</div>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
// render it as an Ajax (asynchronous) call
|
||||
$sHtml .= "<div id=\"$sId\" class=\"display_block loading\">\n";
|
||||
$sHtml .= $oPage->GetP("<img src=\"../images/indicator_arrows.gif\"> Loading...");
|
||||
$sHtml .= "</div>\n";
|
||||
$sHtml .= '
|
||||
<script language="javascript">
|
||||
$.get("ajax.render.php?filter='.$sFilter.'&style='.$this->m_sStyle.'",
|
||||
{ operation: "ajax", extra_params: "'.$sExtraParams.'" },
|
||||
function(data){
|
||||
$("#'.$sId.'").empty();
|
||||
$("#'.$sId.'").append(data);
|
||||
$("#'.$sId.'").removeClass("loading");
|
||||
$("#'.$sId.' .listResults").tablesorter( { headers: { 0:{sorter: false }}, widgets: [\'zebra\']} ); // sortable and zebra tables
|
||||
}
|
||||
);
|
||||
</script>';
|
||||
}
|
||||
if ($bAutoReload)
|
||||
{
|
||||
$sHtml .= '
|
||||
<script language="javascript">
|
||||
setInterval("ReloadBlock(\''.$sId.'\', \''.$this->m_sStyle.'\', \''.$sFilter.'\', \"'.$sExtraParams.'\")", '.$iReloadInterval.');
|
||||
</script>';
|
||||
}
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
||||
{
|
||||
$oPage->add($this->GetRenderContent($oPage, $aExtraParams));
|
||||
}
|
||||
|
||||
public function GetRenderContent(WebPage $oPage, $aExtraParams = array())
|
||||
{
|
||||
$sHtml = '';
|
||||
// Add the extra params into the filter if they make sense for such a filter
|
||||
$bDoSearch = utils::ReadParam('dosearch', false);
|
||||
if ($this->m_oSet == null)
|
||||
{
|
||||
if ($this->m_sStyle != 'links')
|
||||
{
|
||||
$aFilterCodes = array_keys(MetaModel::GetClassFilterDefs($this->m_oFilter->GetClass()));
|
||||
foreach($aFilterCodes as $sFilterCode)
|
||||
{
|
||||
$sExternalFilterValue = utils::ReadParam($sFilterCode, '');
|
||||
if (isset($aExtraParams[$sFilterCode]))
|
||||
{
|
||||
$this->m_oFilter->AddCondition($sFilterCode, $aExtraParams[$sFilterCode]); // Use the default 'loose' operator
|
||||
}
|
||||
else if ($bDoSearch && $sExternalFilterValue != "")
|
||||
{
|
||||
$this->m_oFilter->AddCondition($sFilterCode, $sExternalFilterValue); // Use the default 'loose' operator
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->m_oSet = new CMDBObjectSet($this->m_oFilter);
|
||||
}
|
||||
switch($this->m_sStyle)
|
||||
{
|
||||
case 'count':
|
||||
if (isset($aExtraParams['group_by']))
|
||||
{
|
||||
$sGroupByField = $aExtraParams['group_by'];
|
||||
$aGroupBy = array();
|
||||
while($oObj = $this->m_oSet->Fetch())
|
||||
{
|
||||
$sValue = $oObj->GetAsHtml($sGroupByField);
|
||||
$aGroupBy[$sValue] = isset($aGroupBy[$sValue]) ? $aGroupBy[$sValue]+1 : 1;
|
||||
}
|
||||
$sFilter = urlencode($this->m_oFilter->serialize());
|
||||
$aData = array();
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sParams = $oAppContext->GetForLink();
|
||||
foreach($aGroupBy as $sValue => $iCount)
|
||||
{
|
||||
$aData[] = array ( 'group' => $sValue,
|
||||
'value' => "<a href=\"./UI.php?operation=search&dosearch=1&$sParams&filter=$sFilter&$sGroupByField=".urlencode($sValue)."\">$iCount</a>"); // TO DO: add the context information
|
||||
}
|
||||
$sHtml .= $oPage->GetTable(array('group' => array('label' => MetaModel::GetLabel($this->m_oFilter->GetClass(), $sGroupByField), 'description' => ''), 'value' => array('label'=>'Count', 'description' => 'Number of elements')), $aData);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Simply count the number of elements in the set
|
||||
$iCount = $oSet->Count();
|
||||
$sHtml .= $oPage->GetP("$iCount objects matching the criteria.");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'list':
|
||||
if ( ($this->m_oSet->Count()> 0) && (UserRights::IsActionAllowed($this->m_oSet->GetClass(), UR_ACTION_READ, $this->m_oSet) == UR_ALLOWED_YES) )
|
||||
{
|
||||
$sHtml .= cmdbAbstractObject::GetDisplaySet($oPage, $this->m_oSet, $aExtraParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml .= $oPage->GetP("No object to display.");
|
||||
$sClass = $this->m_oFilter->GetClass();
|
||||
$bDisplayMenu = isset($aExtraParams['menu']) ? $aExtraParams['menu'] == true : true;
|
||||
if ($bDisplayMenu)
|
||||
{
|
||||
if (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES)
|
||||
{
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sParams = $oAppContext->GetForLink();
|
||||
// 1:n links, populate the target object as a default value when creating a new linked object
|
||||
if (isset($aExtraParams['target_attr']))
|
||||
{
|
||||
$aExtraParams['default'][$aExtraParams['target_attr']] = $aExtraParams['object_id'];
|
||||
}
|
||||
$sDefault = '';
|
||||
if (!empty($aExtraParams['default']))
|
||||
{
|
||||
foreach($aExtraParams['default'] as $sKey => $sValue)
|
||||
{
|
||||
$sDefault.= "&default[$sKey]=$sValue";
|
||||
}
|
||||
}
|
||||
|
||||
$sHtml .= $oPage->GetP("<a href=\"./UI.php?operation=new&class=$sClass&$sParams{$sDefault}\">Click here to create a new ".Metamodel::GetName($sClass)."</a>\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'links':
|
||||
//$bDashboardMode = isset($aExtraParams['dashboard']) ? ($aExtraParams['dashboard'] == 'true') : false;
|
||||
//$bSelectMode = isset($aExtraParams['select']) ? ($aExtraParams['select'] == 'true') : false;
|
||||
if ( ($this->m_oSet->Count()> 0) && (UserRights::IsActionAllowed($this->m_oSet->GetClass(), UR_ACTION_READ, $this->m_oSet) == UR_ALLOWED_YES) )
|
||||
{
|
||||
//$sLinkage = isset($aExtraParams['linkage']) ? $aExtraParams['linkage'] : '';
|
||||
$sHtml .= cmdbAbstractObject::GetDisplaySet($oPage, $this->m_oSet, $aExtraParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sClass = $this->m_oFilter->GetClass();
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $this->m_aParams['target_attr']);
|
||||
$sTargetClass = $oAttDef->GetTargetClass();
|
||||
$sHtml .= $oPage->GetP("No ".MetaModel::GetName($sTargetClass)." to display.");
|
||||
$bDisplayMenu = isset($this->m_aParams['menu']) ? $this->m_aParams['menu'] == true : true;
|
||||
if ($bDisplayMenu)
|
||||
{
|
||||
if (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES)
|
||||
{
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sParams = $oAppContext->GetForLink();
|
||||
$sHtml .= $oPage->GetP("<a href=\"../pages/UI.php?operation=modify_links&class=$sClass&sParams&link_attr=".$aExtraParams['link_attr']."&id=".$aExtraParams['object_id']."&target_class=$sTargetClass&addObjects=true\">Click here to add new ".Metamodel::GetName($sTargetClass)."s</a>\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'details':
|
||||
if (UserRights::IsActionAllowed($this->m_oSet->GetClass(), UR_ACTION_READ, $this->m_oSet) == UR_ALLOWED_YES)
|
||||
{
|
||||
while($oObj = $this->m_oSet->Fetch())
|
||||
{
|
||||
$sHtml .= $oObj->GetDetails($oPage); // Still used ???
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'bare_details':
|
||||
if (UserRights::IsActionAllowed($this->m_oSet->GetClass(), UR_ACTION_READ, $this->m_oSet) == UR_ALLOWED_YES)
|
||||
{
|
||||
while($oObj = $this->m_oSet->Fetch())
|
||||
{
|
||||
$sHtml .= $oObj->GetBareDetails($oPage);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'csv':
|
||||
if (UserRights::IsActionAllowed($this->m_oSet->GetClass(), UR_ACTION_READ, $this->m_oSet) == UR_ALLOWED_YES)
|
||||
{
|
||||
$sHtml .= "<textarea style=\"width:95%;height:98%\">\n";
|
||||
$sHtml .= cmdbAbstractObject::GetSetAsCSV($this->m_oSet);
|
||||
$sHtml .= "</textarea>\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'modify':
|
||||
if (UserRights::IsActionAllowed($this->m_oSet->GetClass(), UR_ACTION_MODIFY, $this->m_oSet) == UR_ALLOWED_YES)
|
||||
{
|
||||
while($oObj = $this->m_oSet->Fetch())
|
||||
{
|
||||
$sHtml .= $oObj->GetModifyForm($oPage);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'search':
|
||||
$iSearchSectionId = 1;
|
||||
$sStyle = (isset($aExtraParams['open']) && ($aExtraParams['open'] == 'true')) ? 'SearchDrawer' : 'SearchDrawer DrawerClosed';
|
||||
$sHtml .= "<div id=\"Search_$iSearchSectionId\" class=\"$sStyle\">\n";
|
||||
$oPage->add_ready_script("\$(\"#LnkSearch_$iSearchSectionId\").click(function() {\$(\"#Search_$iSearchSectionId\").slideToggle('normal'); $(\"#LnkSearch_$iSearchSectionId\").toggleClass('open');});");
|
||||
$sHtml .= cmdbAbstractObject::GetSearchForm($oPage, $this->m_oSet, $aExtraParams);
|
||||
$sHtml .= "</div>\n";
|
||||
$sHtml .= "<div class=\"HRDrawer\"></div>\n";
|
||||
$sHtml .= "<div id=\"LnkSearch_$iSearchSectionId\" class=\"DrawerHandle\">Search</div>\n";
|
||||
break;
|
||||
|
||||
case 'pie_chart':
|
||||
$sGroupBy = isset($aExtraParams['group_by']) ? $aExtraParams['group_by'] : '';
|
||||
$sFilter = $this->m_oFilter->ToOQL();
|
||||
$sHtml .= "
|
||||
<OBJECT classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"
|
||||
codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0\"
|
||||
WIDTH=\"400\"
|
||||
HEIGHT=\"250\"
|
||||
id=\"charts\"
|
||||
ALIGN=\"\">
|
||||
<PARAM NAME=movie VALUE=\"../images/charts.swf?library_path=../images/charts_library&xml_source=".urlencode("../pages/ajax.render.php?operation=pie_chart&group_by=$sGroupBy&encoding=oql&filter=".urlencode($sFilter))."\">
|
||||
<PARAM NAME=\"quality\" VALUE=\"high\">
|
||||
<PARAM NAME=\"bgcolor\" VALUE=\"#ffffff\">
|
||||
|
||||
<EMBED src=\"../images/charts.swf?library_path=../images/charts_library&xml_source=".urlencode("../pages/ajax.render.php?operation=pie_chart&group_by=$sGroupBy&encoding=oql&filter=".urlencode($sFilter))."\"
|
||||
quality=\"high\"
|
||||
bgcolor=\"#ffffff\"
|
||||
WIDTH=\"400\"
|
||||
HEIGHT=\"250\"
|
||||
NAME=\"charts\"
|
||||
ALIGN=\"\"
|
||||
swLiveConnect=\"true\"
|
||||
TYPE=\"application/x-shockwave-flash\"
|
||||
PLUGINSPAGE=\"http://www.macromedia.com/go/getflashplayer\">
|
||||
</EMBED>
|
||||
</OBJECT>
|
||||
";
|
||||
break;
|
||||
|
||||
case 'pie_chart_ajax':
|
||||
if (isset($aExtraParams['group_by']))
|
||||
{
|
||||
$sGroupByField = $aExtraParams['group_by'];
|
||||
$aGroupBy = array();
|
||||
while($oObj = $this->m_oSet->Fetch())
|
||||
{
|
||||
$sValue = $oObj->Get($sGroupByField);
|
||||
$aGroupBy[$sValue] = isset($aGroupBy[$sValue]) ? $aGroupBy[$sValue]+1 : 1;
|
||||
}
|
||||
$sFilter = urlencode($this->m_oFilter->serialize());
|
||||
$aData = array();
|
||||
$sHtml .= "<chart>\n";
|
||||
$sHtml .= "<chart_type>3d pie</chart_type>\n";
|
||||
$sHtml .= "<chart_data>\n";
|
||||
$sHtml .= "<row>\n";
|
||||
$sHtml .= "<null/>\n";
|
||||
foreach($aGroupBy as $sValue => $void)
|
||||
{
|
||||
$sHtml .= "<string>$sValue</string>\n";
|
||||
}
|
||||
$sHtml .= "</row>\n";
|
||||
$sHtml .= "<row>\n";
|
||||
$sHtml .= "<string></string>\n";
|
||||
foreach($aGroupBy as $void => $iCount)
|
||||
{
|
||||
$sHtml .= "<number>$iCount</number>\n";
|
||||
}
|
||||
$sHtml .= "</row>\n";
|
||||
$sHtml .= "</chart_data>\n";
|
||||
$sHtml .= "
|
||||
<chart_value color='ffffff' alpha='90' font='arial' bold='true' size='10' position='inside' prefix='' suffix='' decimals='0' separator='' as_percentage='true' />
|
||||
|
||||
<draw>
|
||||
<text color='000000' alpha='10' font='arial' rotation='0' bold='true' size='30' x='0' y='140' width='400' height='150' h_align='center' v_align='bottom'>|||||||||||||||||||||||||||||||||||||||||||||||</text>
|
||||
</draw>
|
||||
|
||||
<legend_label layout='horizontal' bullet='circle' font='arial' bold='true' size='13' color='000000' alpha='85' />
|
||||
<legend_rect fill_color='ffffff' fill_alpha='10' line_color='ffffff' line_alpha='50' line_thickness='0' />
|
||||
<series_color>
|
||||
<color>ddaa41</color>
|
||||
<color>88dd11</color>
|
||||
<color>4e62dd</color>
|
||||
<color>ff8811</color>
|
||||
<color>4d4d4d</color>
|
||||
<color>5a4b6e</color>
|
||||
<color>1188ff</color>
|
||||
</series_color>
|
||||
";
|
||||
$sHtml .= "</chart>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Simply count the number of elements in the set
|
||||
$iCount = $oSet->Count();
|
||||
$sHtml .= "<chart>\n</chart>\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'open_flash_chart':
|
||||
static $iChartCounter = 0;
|
||||
$sChartType = isset($aExtraParams['chart_type']) ? $aExtraParams['chart_type'] : 'pie';
|
||||
$sTitle = isset($aExtraParams['chart_title']) ? $aExtraParams['chart_title'] : '';
|
||||
$sGroupBy = isset($aExtraParams['group_by']) ? $aExtraParams['group_by'] : '';
|
||||
$sFilter = $this->m_oFilter->ToOQL();
|
||||
$sHtml .= "<script>
|
||||
swfobject.embedSWF(\"../images/open-flash-chart.swf\", \"my_chart_{$iChartCounter}\", \"400\", \"400\",\"9.0.0\", \"expressInstall.swf\",
|
||||
{\"data-file\":\"".urlencode("../pages/ajax.render.php?operation=open_flash_chart¶ms[group_by]=$sGroupBy¶ms[chart_type]=$sChartType¶ms[chart_title]=$sTitle&encoding=oql&filter=".urlencode($sFilter))."\"});
|
||||
</script>\n";
|
||||
$sHtml .= "<div id=\"my_chart_{$iChartCounter}\">If the chart does not display, <a href=\"http://get.adobe.com/flash/\" target=\"_blank\">install Flash</a></div>\n";
|
||||
$iChartCounter++;
|
||||
break;
|
||||
|
||||
case 'open_flash_chart_ajax':
|
||||
include './php-ofc-library/open-flash-chart.php';
|
||||
$sChartType = isset($aExtraParams['chart_type']) ? $aExtraParams['chart_type'] : 'pie';
|
||||
|
||||
$oChart = new open_flash_chart();
|
||||
switch($sChartType)
|
||||
{
|
||||
case 'bars':
|
||||
$oChartElement = new bar_glass();
|
||||
|
||||
if (isset($aExtraParams['group_by']))
|
||||
{
|
||||
$sGroupByField = $aExtraParams['group_by'];
|
||||
$aGroupBy = array();
|
||||
while($oObj = $this->m_oSet->Fetch())
|
||||
{
|
||||
$sValue = $oObj->Get($sGroupByField);
|
||||
$aGroupBy[$sValue] = isset($aGroupBy[$sValue]) ? $aGroupBy[$sValue]+1 : 1;
|
||||
}
|
||||
$sFilter = urlencode($this->m_oFilter->serialize());
|
||||
$aData = array();
|
||||
$aLabels = array();
|
||||
foreach($aGroupBy as $sValue => $iValue)
|
||||
{
|
||||
$aData[] = $iValue;
|
||||
$aLabels[] = $sValue;
|
||||
}
|
||||
$maxValue = max($aData);
|
||||
$oYAxis = new y_axis();
|
||||
$aMagicValues = array(1,2,5,10);
|
||||
$iMultiplier = 1;
|
||||
$index = 0;
|
||||
$iTop = $aMagicValues[$index % count($aMagicValues)]*$iMultiplier;
|
||||
while($maxValue > $iTop)
|
||||
{
|
||||
$index++;
|
||||
$iTop = $aMagicValues[$index % count($aMagicValues)]*$iMultiplier;
|
||||
if (($index % count($aMagicValues)) == 0)
|
||||
{
|
||||
$iMultiplier = $iMultiplier * 10;
|
||||
}
|
||||
}
|
||||
//echo "oYAxis->set_range(0, $iTop, $iMultiplier);\n";
|
||||
$oYAxis->set_range(0, $iTop, $iMultiplier);
|
||||
$oChart->set_y_axis( $oYAxis );
|
||||
|
||||
$oChartElement->set_values( $aData );
|
||||
$oXAxis = new x_axis();
|
||||
$oXLabels = new x_axis_labels();
|
||||
// set them vertical
|
||||
$oXLabels->set_vertical();
|
||||
// set the label text
|
||||
$oXLabels->set_labels($aLabels);
|
||||
// Add the X Axis Labels to the X Axis
|
||||
$oXAxis->set_labels( $oXLabels );
|
||||
$oChart->set_x_axis( $oXAxis );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'pie':
|
||||
default:
|
||||
$oChartElement = new pie();
|
||||
$oChartElement->set_start_angle( 35 );
|
||||
$oChartElement->set_animate( true );
|
||||
$oChartElement->set_tooltip( '#label# - #val# (#percent#)' );
|
||||
if (isset($aExtraParams['group_by']))
|
||||
{
|
||||
$sGroupByField = $aExtraParams['group_by'];
|
||||
$aGroupBy = array();
|
||||
while($oObj = $this->m_oSet->Fetch())
|
||||
{
|
||||
$sValue = $oObj->Get($sGroupByField);
|
||||
$aGroupBy[$sValue] = isset($aGroupBy[$sValue]) ? $aGroupBy[$sValue]+1 : 1;
|
||||
}
|
||||
$sFilter = urlencode($this->m_oFilter->serialize());
|
||||
$aData = array();
|
||||
foreach($aGroupBy as $sValue => $iValue)
|
||||
{
|
||||
$aData[] = new pie_value($iValue, $sValue);
|
||||
}
|
||||
|
||||
|
||||
$oChartElement->set_values( $aData );
|
||||
$oChart->x_axis = null;
|
||||
}
|
||||
}
|
||||
if (isset($aExtraParams['chart_title'])) //@@ BUG: not passed via ajax !!!
|
||||
{
|
||||
$oTitle = new title( $aExtraParams['chart_title'] );
|
||||
$oChart->set_title( $oTitle );
|
||||
}
|
||||
$oChart->set_bg_colour('#FFFFFF');
|
||||
$oChart->add_element( $oChartElement );
|
||||
|
||||
$sHtml = $oChart->toPrettyString();
|
||||
break;
|
||||
|
||||
default:
|
||||
// Unsupported style, do nothing.
|
||||
$sHtml .= "Error: unsupported style of block: ".$this->m_sStyle;
|
||||
}
|
||||
return $sHtml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class to manage 'blocks' of HTML pieces that are parts of a page and contain some list of cmdb objects
|
||||
*
|
||||
* Each block is actually rendered as a <div></div> tag that can be rendered synchronously
|
||||
* or as a piece of Javascript/JQuery/Ajax that will get its content from another page (ajax.render.php).
|
||||
* The list of cmdbObjects to be displayed into the block is defined by a filter
|
||||
* Right now the type of display is either: list, count or details
|
||||
* - list produces a table listing the objects
|
||||
* - count produces a paragraphs with a sentence saying 'cont' objects found
|
||||
* - details display (as table) the details of each object found (best if only one)
|
||||
*/
|
||||
class HistoryBlock extends DisplayBlock
|
||||
{
|
||||
public function GetRenderContent(WebPage $oPage, $aExtraParams = array())
|
||||
{
|
||||
$sHtml = '';
|
||||
// Add the extra params into the filter if they make sense for such a filter
|
||||
$aFilterCodes = array_keys(MetaModel::GetClassFilterDefs($this->m_oFilter->GetClass()));
|
||||
foreach($aFilterCodes as $sFilterCode)
|
||||
{
|
||||
if (isset($aExtraParams[$sFilterCode]))
|
||||
{
|
||||
$this->m_oFilter->AddCondition($sFilterCode, $aExtraParams[$sFilterCode]); // Use the default 'loose' operator
|
||||
}
|
||||
}
|
||||
$oSet = new CMDBObjectSet($this->m_oFilter, array('date'=>false));
|
||||
$sHtml .= "<!-- filter: ".($this->m_oFilter->ToOQL())."-->\n";
|
||||
switch($this->m_sStyle)
|
||||
{
|
||||
case 'toggle':
|
||||
// First the latest change that the user is allowed to see
|
||||
do
|
||||
{
|
||||
$oLatestChangeOp = $oSet->Fetch();
|
||||
}
|
||||
while(is_object($oLatestChangeOp) && ($oLatestChangeOp->GetDescription() == ''));
|
||||
|
||||
if (is_object($oLatestChangeOp))
|
||||
{
|
||||
global $oContext; // User Context.. should be statis instead of global...
|
||||
// There is one change in the list... only when the object has been created !
|
||||
$sDate = $oLatestChangeOp->GetAsHTML('date');
|
||||
$oChange = $oContext->GetObject('CMDBChange', $oLatestChangeOp->Get('change'));
|
||||
$sUserInfo = $oChange->GetAsHTML('userinfo');
|
||||
$oSet->Rewind(); // Reset the pointer to the beginning of the set
|
||||
$sHtml .= $oPage->GetStartCollapsibleSection("Last modified on $sDate by $sUserInfo.");
|
||||
//$sHtml .= cmdbAbstractObject::GetDisplaySet($oPage, $oSet);
|
||||
$aChanges = array();
|
||||
while($oChangeOp = $oSet->Fetch())
|
||||
{
|
||||
$sChangeDescription = $oChangeOp->GetDescription();
|
||||
if ($sChangeDescription != '')
|
||||
{
|
||||
// The change is visible for the current user
|
||||
$changeId = $oChangeOp->Get('change');
|
||||
$aChanges[$changeId]['date'] = $oChangeOp->Get('date');
|
||||
$aChanges[$changeId]['userinfo'] = $oChangeOp->Get('userinfo');
|
||||
if (!isset($aChanges[$changeId]['log']))
|
||||
{
|
||||
$aChanges[$changeId]['log'] = array();
|
||||
}
|
||||
$aChanges[$changeId]['log'][] = $sChangeDescription;
|
||||
}
|
||||
}
|
||||
$aAttribs = array('date' => array('label' => 'Date', 'description' => 'Date of the change'),
|
||||
'userinfo' => array('label' => 'User', 'description' => 'User who made the change'),
|
||||
'log' => array('label' => 'Changes', 'description' => 'Changes made to the object'),
|
||||
);
|
||||
$aValues = array();
|
||||
foreach($aChanges as $aChange)
|
||||
{
|
||||
$aValues[] = array('date' => $aChange['date'], 'userinfo' => $aChange['userinfo'], 'log' => "<ul><li>".implode('</li><li>', $aChange['log'])."</li></ul>");
|
||||
}
|
||||
$sHtml .= $oPage->GetTable($aAttribs, $aValues);
|
||||
$sHtml .= $oPage->GetEndCollapsibleSection();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$sHtml .= parent::GetRenderContent($oPage, $aExtraParams);
|
||||
}
|
||||
return $sHtml;
|
||||
}
|
||||
}
|
||||
|
||||
class MenuBlock extends DisplayBlock
|
||||
{
|
||||
public function GetRenderContent(WebPage $oPage, $aExtraParams = array())
|
||||
{
|
||||
$sHtml = '';
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sContext = $oAppContext->GetForLink();
|
||||
$sClass = $this->m_oFilter->GetClass();
|
||||
$oSet = new CMDBObjectSet($this->m_oFilter);
|
||||
$sFilter = $this->m_oFilter->serialize();
|
||||
$aActions = array();
|
||||
$sUIPage = cmdbAbstractObject::ComputeUIPage($sClass);
|
||||
// 1:n links, populate the target object as a default value when creating a new linked object
|
||||
if (isset($aExtraParams['target_attr']))
|
||||
{
|
||||
$aExtraParams['default'][$aExtraParams['target_attr']] = $aExtraParams['object_id'];
|
||||
}
|
||||
$sDefault = '';
|
||||
if (!empty($aExtraParams['default']))
|
||||
{
|
||||
foreach($aExtraParams['default'] as $sKey => $sValue)
|
||||
{
|
||||
$sDefault.= "&default[$sKey]=$sValue";
|
||||
}
|
||||
}
|
||||
switch($oSet->Count())
|
||||
{
|
||||
case 0:
|
||||
// No object in the set, the only possible action is "new"
|
||||
$bIsModifyAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY);
|
||||
if ($bIsModifyAllowed) { $aActions[] = array ('label' => 'New', 'url' => "../page/$sUIPage?operation=new&class=$sClass&$sContext{$sDefault}"); }
|
||||
break;
|
||||
|
||||
case 1:
|
||||
$oObj = $oSet->Fetch();
|
||||
$id = $oObj->GetKey();
|
||||
$bIsModifyAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet);
|
||||
$bIsDeleteAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_DELETE, $oSet);
|
||||
$bIsBulkModifyAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_MODIFY, $oSet);
|
||||
$bIsBulkDeleteAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_DELETE, $oSet);
|
||||
// Just one object in the set, possible actions are "new / clone / modify and delete"
|
||||
if (isset($aExtraParams['link_attr']))
|
||||
{
|
||||
$id = $aExtraParams['object_id'];
|
||||
$sTargetAttr = $aExtraParams['target_attr'];
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sTargetAttr);
|
||||
$sTargetClass = $oAttDef->GetTargetClass();
|
||||
if ($bIsModifyAllowed) { $aActions[] = array ('label' => 'Add...', 'url' => "../pages/$sUIPage?operation=modify_links&class=$sClass&link_attr=".$aExtraParams['link_attr']."&target_class=$sTargetClass&id=$id&addObjects=true&$sContext"); }
|
||||
if ($bIsModifyAllowed) { $aActions[] = array ('label' => 'Manage...', 'url' => "../pages/$sUIPage?operation=modify_links&class=$sClass&link_attr=".$aExtraParams['link_attr']."&target_class=$sTargetClass&id=$id&sContext"); }
|
||||
//if ($bIsDeleteAllowed) { $aActions[] = array ('label' => 'Remove All', 'url' => "#"); }
|
||||
}
|
||||
else
|
||||
{
|
||||
$sUrl = utils::GetAbsoluteUrl();
|
||||
$aActions[] = array ('label' => 'eMail', 'url' => "mailto:?subject=".$oSet->GetFilter()->__DescribeHTML()."&body=".urlencode("$sUrl?operation=search&filter=$sFilter&$sContext"));
|
||||
$aActions[] = array ('label' => 'CSV Export', 'url' => "../pages/$sUIPage?operation=search&filter=$sFilter&format=csv&$sContext");
|
||||
//$aActions[] = array ('label' => 'Bookmark...', 'url' => "../pages/ajax.render.php?operation=create&class=$sClass&filter=$sFilter", 'class' => 'jqmTrigger');
|
||||
if ($bIsModifyAllowed) { $aActions[] = array ('label' => 'New...', 'url' => "../pages/$sUIPage?operation=new&class=$sClass&$sContext{$sDefault}"); }
|
||||
//if ($bIsModifyAllowed) { $aActions[] = array ('label' => 'Clone...', 'url' => "../pages/$sUIPage?operation=clone&class=$sClass&id=$id&$sContext"); }
|
||||
if ($bIsModifyAllowed) { $aActions[] = array ('label' => 'Modify...', 'url' => "../pages/$sUIPage?operation=modify&class=$sClass&id=$id&$sContext"); }
|
||||
if ($bIsDeleteAllowed) { $aActions[] = array ('label' => 'Delete...', 'url' => "../pages/$sUIPage?operation=delete&class=$sClass&id=$id&$sContext"); }
|
||||
}
|
||||
$aTransitions = $oObj->EnumTransitions();
|
||||
$aStimuli = Metamodel::EnumStimuli($sClass);
|
||||
foreach($aTransitions as $sStimulusCode => $aTransitionDef)
|
||||
{
|
||||
$iActionAllowed = UserRights::IsStimulusAllowed($sClass, $sStimulusCode, $oSet);
|
||||
switch($iActionAllowed)
|
||||
{
|
||||
case UR_ALLOWED_YES:
|
||||
$aActions[] = array('label' => $aStimuli[$sStimulusCode]->Get('label'), 'url' => "../pages/UI.php?operation=stimulus&stimulus=$sStimulusCode&class=$sClass&id=$id&$sContext");
|
||||
break;
|
||||
|
||||
case UR_ALLOWED_DEPENDS:
|
||||
$aActions[] = array('label' => $aStimuli[$sStimulusCode]->Get('label').' (*)', 'url' => "../pages/UI.php?operation=stimulus&stimulus=$sStimulusCode&class=$sClass&id=$id&$sContext");
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
//print_r($aTransitions);
|
||||
break;
|
||||
|
||||
default:
|
||||
// Check rights
|
||||
// New / Modify
|
||||
$bIsModifyAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet);
|
||||
$bIsBulkModifyAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_MODIFY, $oSet);
|
||||
$bIsBulkDeleteAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_DELETE, $oSet);
|
||||
if (isset($aExtraParams['link_attr']))
|
||||
{
|
||||
$id = $aExtraParams['object_id'];
|
||||
$sTargetAttr = $aExtraParams['target_attr'];
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sTargetAttr);
|
||||
$sTargetClass = $oAttDef->GetTargetClass();
|
||||
$bIsDeleteAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_DELETE, $oSet);
|
||||
if ($bIsModifyAllowed) { $aActions[] = array ('label' => 'Add...', 'url' => "../pages/$sUIPage?operation=modify_links&class=$sClass&link_attr=".$aExtraParams['link_attr']."&target_class=$sTargetClass&id=$id&addObjects=true&$sContext"); }
|
||||
//if ($bIsBulkModifyAllowed) { $aActions[] = array ('label' => 'Add...', 'url' => "../pages/$sUIPage?operation=modify_links&class=$sClass&linkage=".$aExtraParams['linkage']."&id=$id&addObjects=true&$sContext"); }
|
||||
if ($bIsBulkModifyAllowed) { $aActions[] = array ('label' => 'Manage...', 'url' => "../pages/$sUIPage?operation=modify_links&class=$sClass&link_attr=".$aExtraParams['link_attr']."&target_class=$sTargetClass&id=$id&sContext"); }
|
||||
//if ($bIsBulkDeleteAllowed) { $aActions[] = array ('label' => 'Remove All...', 'url' => "#"); }
|
||||
}
|
||||
else
|
||||
{
|
||||
// many objects in the set, possible actions are: new / modify all / delete all
|
||||
$sUrl = utils::GetAbsoluteUrl();
|
||||
$aActions[] = array ('label' => 'eMail', 'url' => "mailto:?subject=".$oSet->GetFilter()->__DescribeHTML()."&body=".urlencode("$sUrl?operation=search&filter=$sFilter&$sContext"));
|
||||
$aActions[] = array ('label' => 'CSV Export', 'url' => "../pages/$sUIPage?operation=search&filter=$sFilter&format=csv&$sContext");
|
||||
//$aActions[] = array ('label' => 'Bookmark...', 'url' => "../pages/ajax.render.php?operation=create&class=$sClass&filter=$sFilter", 'class' => 'jqmTrigger');
|
||||
if ($bIsModifyAllowed) { $aActions[] = array ('label' => 'New...', 'url' => "../pages/$sUIPage?operation=new&class=$sClass&$sContext{$sDefault}"); }
|
||||
//if ($bIsBulkModifyAllowed) { $aActions[] = array ('label' => 'Modify All...', 'url' => "../pages/$sUIPage?operation=modify_all&filter=$sFilter&$sContext"); }
|
||||
//if ($bIsBulkDeleteAllowed) { $aActions[] = array ('label' => 'Delete All...', 'url' => "../pages/$sUIPage?operation=delete_all&filter=$sFilter&$sContext"); }
|
||||
}
|
||||
}
|
||||
$sHtml .= "<div class=\"jd_menu_itop\"><ul class=\"jd_menu jd_menu_itop\">\n<li>Actions\n<ul>\n";
|
||||
foreach ($aActions as $aAction)
|
||||
{
|
||||
$sClass = isset($aAction['class']) ? " class=\"{$aAction['class']}\"" : "";
|
||||
$sHtml .= "<li><a href=\"{$aAction['url']}\"$sClass>{$aAction['label']}</a></li>\n<li>\n";
|
||||
}
|
||||
$sHtml .= "</ul>\n</li>\n</ul></div>\n";
|
||||
$oPage->add_ready_script("$(\"ul.jd_menu\").jdMenu();\n");
|
||||
return $sHtml;
|
||||
}
|
||||
}
|
||||
?>
|
||||
54
application/iotask.class.inc.php
Normal file
54
application/iotask.class.inc.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
require_once('../application/cmdbabstract.class.inc.php');
|
||||
|
||||
/**
|
||||
* This class manages the input/output tasks
|
||||
* for synchronizing information with external data sources
|
||||
*/
|
||||
class InputOutputTask extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "application",
|
||||
"name" => "IOTask",
|
||||
"description" => "Input / Output Task for synchronizing information with external data sources",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_iotask",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Task Name", "description"=>"Short name for this task", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("label"=>"Task Description", "description"=>"Long description for this task", "allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("category", array("label"=>"Category", "description"=>"Type of task", "allowed_values"=>new ValueSetEnum('Input, Ouput'), "sql"=>"category", "default_value"=>"Input", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("source_type", array("label"=>"Source Type", "description"=>"Type of data source", "allowed_values"=>new ValueSetEnum('File, Database, Web Service'), "sql"=>"source_type", "default_value"=>"File", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("source_subtype", array("label"=>"Source Subtype", "description"=>"Subtype of Data Source", "allowed_values"=>new ValueSetEnum('Oracle, MySQL, Postgress, MSSQL, SOAP, HTTP-Get, HTTP-Post, XML/RPC, CSV, XML, Excel'), "sql"=>"source_subtype", "default_value"=>"CSV", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("source_path", array("label"=>"Source Path", "description"=>"Path to the icon o the menu", "allowed_values"=>null, "sql"=>"source_path", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeClass("objects_class", array("label"=>"Objects Class", "description"=>"Class of the objects processed by this task", "class_category"=>"", "more_values"=>"", "sql"=>"objects_class", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("test_mode", array("label"=>"Test Mode", "description"=>"If set to 'Yes' the modifications are not applied", "allowed_values"=>new ValueSetEnum('Yes,No'), "sql"=>"test_mode", "default_value"=>'No', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("verbose_mode", array("label"=>"Verbose Mode", "description"=>"If set to 'Yes' extra debug information is added to the log", "allowed_values"=>new ValueSetEnum('Yes,No'), "sql"=>"verbose_mode", "default_value" => 'No', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("options", array("label"=>"Options", "description"=>"Reconciliation options", "allowed_values"=>new ValueSetEnum('Full, Update Only, Creation Only'), "sql"=>"options", "default_value"=> 'Full', "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("description");
|
||||
MetaModel::Init_AddFilterFromAttribute("category");
|
||||
MetaModel::Init_AddFilterFromAttribute("source_type");
|
||||
MetaModel::Init_AddFilterFromAttribute("source_subtype");
|
||||
MetaModel::Init_AddFilterFromAttribute("objects_class");
|
||||
|
||||
// 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('list', array('name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype', 'options')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'category', 'objects_class', 'source_type', 'source_subtype')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
?>
|
||||
458
application/itopwebpage.class.inc.php
Normal file
458
application/itopwebpage.class.inc.php
Normal file
@@ -0,0 +1,458 @@
|
||||
<?php
|
||||
require_once("../application/nicewebpage.class.inc.php");
|
||||
require_once("../application/usercontext.class.inc.php");
|
||||
require_once("../application/applicationcontext.class.inc.php");
|
||||
/**
|
||||
* Web page with some associated CSS and scripts (jquery) for a fancier display
|
||||
*/
|
||||
class iTopWebPage extends NiceWebPage
|
||||
{
|
||||
private $m_sMenu;
|
||||
private $m_currentOrganization;
|
||||
private $m_aTabs;
|
||||
private $m_sCurrentTabContainer;
|
||||
private $m_sCurrentTab;
|
||||
|
||||
public function __construct($sTitle, $currentOrganization)
|
||||
{
|
||||
parent::__construct($sTitle);
|
||||
$this->m_sCurrentTabContainer = '';
|
||||
$this->m_sCurrentTab = '';
|
||||
$this->m_aTabs = array();
|
||||
$this->m_sMenu = "";
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sExtraParams = $oAppContext->GetForLink();
|
||||
$this->add_header("Content-type: text/html; charset=utf-8");
|
||||
$this->add_header("Cache-control: no-cache");
|
||||
$this->m_currentOrganization = $currentOrganization;
|
||||
$this->add_linked_script("../js/jquery.dimensions.js");
|
||||
$this->add_linked_script("../js/splitter.js");
|
||||
$this->add_linked_script("../js/jquery.tablehover.js");
|
||||
$this->add_linked_script("../js/jquery.treeview.js");
|
||||
$this->add_linked_script("../js/jquery.autocomplete.js");
|
||||
$this->add_linked_script("../js/jquery.bgiframe.js");
|
||||
$this->add_linked_script("../js/jquery.jdMenu.js");
|
||||
$this->add_linked_script("../js/date.js");
|
||||
$this->add_linked_script("../js/jquery.date.picker.js");
|
||||
$this->add_linked_script("../js/jquery.tablesorter.min.js");
|
||||
$this->add_linked_script("../js/utils.js");
|
||||
//$this->add_linked_script("../js/jquery-ui-personalized-1.5.3.js");
|
||||
$this->add_linked_script("../js/swfobject.js");
|
||||
$this->add_linked_stylesheet("../css/jquery.treeview.css");
|
||||
$this->add_linked_stylesheet("../css/jquery.autocomplete.css");
|
||||
$this->add_linked_stylesheet("../css/date.picker.css");
|
||||
$this->add_ready_script(
|
||||
<<<EOF
|
||||
// Vertical splitter. The min/max/starting sizes for the left (A) pane
|
||||
// are set here. All values are in pixels.
|
||||
$("#MySplitter").splitter({
|
||||
type: "v",
|
||||
minA: 100, initA: 250, maxA: 500,
|
||||
accessKey: "|"
|
||||
});
|
||||
|
||||
// Horizontal splitter, nested in the right pane of the vertical splitter.
|
||||
if ( $("#TopPane").length > 0)
|
||||
{
|
||||
$("#RightPane").splitter({
|
||||
type: "h" //,
|
||||
//minA: 100, initA: 150, maxA: 500,
|
||||
//accessKey: "_"
|
||||
});
|
||||
}
|
||||
|
||||
// Manually set the outer splitter's height to fill the browser window.
|
||||
// This must be re-done any time the browser window is resized.
|
||||
$(window).bind("resize", function(){
|
||||
var ms = $("#MySplitter");
|
||||
var top = ms.offset().top; // from dimensions.js
|
||||
var wh = $(window).height();
|
||||
// Account for margin or border on the splitter container
|
||||
var mrg = parseInt(ms.css("marginBottom")) || 0;
|
||||
var brd = parseInt(ms.css("borderBottomWidth")) || 0;
|
||||
ms.css("height", (wh-top-mrg-brd)+"px");
|
||||
|
||||
// IE fires resize for splitter; others don't so do it here
|
||||
if ( !jQuery.browser.msie )
|
||||
ms.trigger("resize");
|
||||
|
||||
|
||||
}).trigger("resize");
|
||||
|
||||
var ms = $("#MySplitter");
|
||||
ms.trigger("resize");
|
||||
|
||||
if ( $("#TopPane").length > 0)
|
||||
{
|
||||
$("#RightPane").trigger("resize");
|
||||
}
|
||||
|
||||
$("#tabbedContent > ul").tabs( 1, { fxFade: true, fxSpeed: 'fast' } ); // tabs
|
||||
$("table.listResults").tableHover(); // hover tables
|
||||
$(".listResults").tablesorter( { headers: { 0:{sorter: false }}, widgets: ['zebra']} ); // sortable and zebra tables
|
||||
$(".date-pick").datePicker( {clickInput: false, createButton: true, startDate: '2000-01-01'} ); // Date picker
|
||||
$('#ModalDlg').jqm({ajax: '@href', trigger: 'a.jqmTrigger', overlay:70, modal:true, toTop:true}); // jqModal Window
|
||||
|
||||
//$('.display_block').draggable(); // make the blocks draggable
|
||||
EOF
|
||||
);
|
||||
$this->add_script("
|
||||
// For automplete
|
||||
function findValue(li) {
|
||||
if( li == null ) return alert(\"No match!\");
|
||||
|
||||
// if coming from an AJAX call, let's use the CityId as the value
|
||||
if( !!li.extra ) var sValue = li.extra[0];
|
||||
|
||||
// otherwise, let's just display the value in the text box
|
||||
else var sValue = li.selectValue;
|
||||
|
||||
//alert(\"The value you selected was: \" + sValue);
|
||||
}
|
||||
|
||||
function selectItem(li) {
|
||||
findValue(li);
|
||||
}
|
||||
|
||||
function formatItem(row) {
|
||||
return row[0];
|
||||
}
|
||||
|
||||
function goBack()
|
||||
{
|
||||
window.history.back();
|
||||
}
|
||||
");
|
||||
$this->DisplayMenu();
|
||||
}
|
||||
|
||||
public function AddToMenu($sHtml)
|
||||
{
|
||||
$this->m_sMenu .= $sHtml;
|
||||
}
|
||||
|
||||
public function DisplayMenu()
|
||||
{
|
||||
// Combo box to select the organization
|
||||
$this->AddToMenu("<div id=\"OrganizationSelection\">
|
||||
<form style=\"display:inline\" action=\"{$_SERVER['PHP_SELF']}\"><select style=\"width:150px;font-size:x-small\" name=\"org_id\" title=\"Pick an organization\" onChange=\"this.form.submit();\">\n");
|
||||
// List of visible Organizations
|
||||
$oContext = new UserContext();
|
||||
$oSearchFilter = $oContext->NewFilter("bizOrganization");
|
||||
$oSet = new CMDBObjectSet($oSearchFilter);
|
||||
$sSelected = ($this->m_currentOrganization == '') ? ' selected' : '';
|
||||
$this->AddToMenu("<option value=\"\"$sSelected> All Organizations </option>");
|
||||
if ($oSet->Count() > 0)
|
||||
while($oOrg = $oSet->Fetch())
|
||||
{
|
||||
if ($this->m_currentOrganization == $oOrg->GetKey())
|
||||
{
|
||||
$oCurrentOrganization = $oOrg;
|
||||
$sSelected = " selected";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSelected = "";
|
||||
}
|
||||
$this->AddToMenu("<option value=\"".$oOrg->GetKey()."\"$sSelected>".$oOrg->Get('name')."</option>\n");
|
||||
}
|
||||
$this->AddToMenu("</select>\n");
|
||||
// Add other dimensions/context information to this form
|
||||
$oAppContext = new ApplicationContext();
|
||||
$oAppContext->Reset('org_id'); // Org id is handled above and we want to be able to change it here !
|
||||
$this->AddToMenu($oAppContext->GetForForm());
|
||||
$this->AddToMenu("</form>\n");
|
||||
$this->AddToMenu("</div>\n");
|
||||
$this->AddToMenu("<ul id=\"browser\" class=\"dir\">\n");
|
||||
|
||||
// Display the menu
|
||||
$oAppContext = new ApplicationContext();
|
||||
// 1) Application defined menus
|
||||
$oSearchFilter = $oContext->NewFilter("menuNode");
|
||||
$oSearchFilter->AddCondition('parent_id', 0, '=');
|
||||
$oSearchFilter->AddCondition('type', 'application', '=');
|
||||
// There may be more criteria added later to have a specific menu based on the user's profile
|
||||
$oSet = new CMDBObjectSet($oSearchFilter, array('rank' => true));
|
||||
while ($oRootMenuNode = $oSet->Fetch())
|
||||
{
|
||||
$oRootMenuNode->DisplayMenu($this, 'application', $oAppContext->GetAsHash());
|
||||
}
|
||||
// 2) User defined menus (Bookmarks)
|
||||
$oSearchFilter = $oContext->NewFilter("menuNode");
|
||||
$oSearchFilter->AddCondition('parent_id', 0, '=');
|
||||
$oSearchFilter->AddCondition('type', 'user', '=');
|
||||
$oSearchFilter->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||
// There may be more criteria added later to have a specific menu based on the user's profile
|
||||
$oSet = new CMDBObjectSet($oSearchFilter, array('rank' => true));
|
||||
while ($oRootMenuNode = $oSet->Fetch())
|
||||
{
|
||||
$oRootMenuNode->DisplayMenu($this, 'user', $oAppContext->GetAsHash());
|
||||
}
|
||||
// 3) Administrator menu
|
||||
if (userRights::IsAdministrator())
|
||||
{
|
||||
$oSearchFilter = $oContext->NewFilter("menuNode");
|
||||
$oSearchFilter->AddCondition('parent_id', 0, '=');
|
||||
$oSearchFilter->AddCondition('type', 'administrator', '=');
|
||||
// There may be more criteria added later to have a specific menu based on the user's profile
|
||||
$oSet = new CMDBObjectSet($oSearchFilter, array('rank' => true));
|
||||
while ($oRootMenuNode = $oSet->Fetch())
|
||||
{
|
||||
$oRootMenuNode->DisplayMenu($this, 'administrator', $oAppContext->GetAsHash());
|
||||
}
|
||||
}
|
||||
|
||||
$this->AddToMenu("</ul>\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs (via some echo) the complete HTML page by assembling all its elements
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
foreach($this->a_headers as $s_header)
|
||||
{
|
||||
header($s_header);
|
||||
}
|
||||
$s_captured_output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
|
||||
echo "<html>\n";
|
||||
echo "<head>\n";
|
||||
echo "<title>{$this->s_title}</title>\n";
|
||||
echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
|
||||
echo $this->get_base_tag();
|
||||
// Stylesheets MUST be loaded before any scripts otherwise
|
||||
// jQuery scripts may face some spurious problems (like failing on a 'reload')
|
||||
foreach($this->a_linked_stylesheets as $a_stylesheet)
|
||||
{
|
||||
if ($a_stylesheet['condition'] != "")
|
||||
{
|
||||
echo "<!--[if {$a_stylesheet['condition']}]>\n";
|
||||
}
|
||||
echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"{$a_stylesheet['link']}\" />\n";
|
||||
if ($a_stylesheet['condition'] != "")
|
||||
{
|
||||
echo "<![endif]-->\n";
|
||||
}
|
||||
}
|
||||
foreach($this->a_linked_scripts as $s_script)
|
||||
{
|
||||
echo "<script type=\"text/javascript\" src=\"$s_script\"></script>\n";
|
||||
}
|
||||
if (count($this->m_aReadyScripts)>0)
|
||||
{
|
||||
$this->add_script("\$(document).ready(function() {\n".implode("\n", $this->m_aReadyScripts)."\n});");
|
||||
}
|
||||
if (count($this->a_scripts)>0)
|
||||
{
|
||||
echo "<script type=\"text/javascript\">\n";
|
||||
foreach($this->a_scripts as $s_script)
|
||||
{
|
||||
echo "$s_script\n";
|
||||
}
|
||||
echo "</script>\n";
|
||||
}
|
||||
|
||||
if (count($this->a_styles)>0)
|
||||
{
|
||||
echo "<style>\n";
|
||||
foreach($this->a_styles as $s_style)
|
||||
{
|
||||
echo "$s_style\n";
|
||||
}
|
||||
echo "</style>\n";
|
||||
}
|
||||
echo "<link rel=\"search\" type=\"application/opensearchdescription+xml\" title=\"iTop\" href=\"./opensearch.xml.php\" />\n";
|
||||
echo "</head>\n";
|
||||
echo "<body>\n";
|
||||
|
||||
// Display the header
|
||||
if (ITOP_REVISION == '$WCREV$')
|
||||
{
|
||||
// This is NOT a version built using the buil system, just display the main version
|
||||
$sVersionString = "iTop Version ".ITOP_VERSION;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is a build made from SVN, let display the full information
|
||||
$sVersionString = "iTop Version ".ITOP_VERSION." revision ".ITOP_REVISION.", built on: ".ITOP_BUILD_DATE;
|
||||
}
|
||||
echo "<div id=\"Header\">\n";
|
||||
echo "<div class=\"iTopLogo\" title=\"$sVersionString\"><span>iTop</span></div>\n";
|
||||
//echo "<div id=\"GlobalSearch\"><div style=\"border: 1px solid #999; padding:1px; background-color:#fff;\"><img src=\"../images/magnifier.gif\"/><input style=\"border:0\" type=\"text\" size=\"15\" title=\"Global Search\"></input></div></div>\n";
|
||||
$sText = Utils::ReadParam('text', '');
|
||||
$sOnClick = "";
|
||||
if (empty($sText))
|
||||
{
|
||||
// if no search text is supplied then
|
||||
// 1) the search text is filled with "your search"
|
||||
// 2) clicking on it will erase it
|
||||
$sText = "Your search";
|
||||
$sOnClick = " onclick=\"this.value='';this.onclick=null;\"";
|
||||
}
|
||||
$sUserName = UserRights::GetUser();
|
||||
$sIsAdmin = UserRights::IsAdministrator() ? '(Administrator)' : '';
|
||||
echo "<div id=\"Login\" style=\"position:absolute; top:18px; right:16px; width:500px;\">Logged in as '$sUserName' $sIsAdmin ";
|
||||
echo "<form action=\"../pages/UI.php\" method=\"post\" style=\"display:inline\">\n";
|
||||
echo "<input type=\"submit\" value=\"Log off\" />\n";
|
||||
echo "<input type=\"hidden\" name=\"loginop\" value=\"logoff\" />\n";
|
||||
echo "</form>\n";
|
||||
echo "<form action=\"../pages/UI.php\" style=\"display:inline\"><div style=\"padding:1px; background-color:#fff;display:inline;\"><img src=\"../images/magnifier.gif\"/><input style=\"border:0\" type=\"text\" size=\"15\" title=\"Global Search\" name=\"text\" value=\"$sText\"$sOnClick></input></div><input type=\"submit\" value=\"Search\" />
|
||||
<input type=\"hidden\" name=\"operation\" value=\"full_text\" /></form>\n";
|
||||
echo "</div>\n";
|
||||
|
||||
echo "</div>\n";
|
||||
|
||||
// Display the menu
|
||||
echo "<div id=\"MySplitter\">\n";
|
||||
echo " <div id=\"LeftPane\">\n";
|
||||
echo $this->m_sMenu;
|
||||
echo " </div> <!-- LeftPane -->\n";
|
||||
|
||||
echo "<div id=\"RightPane\">\n";
|
||||
|
||||
// Render the tabs in the page (if any)
|
||||
foreach($this->m_aTabs as $sTabContainerName => $m_aTabs)
|
||||
{
|
||||
$sTabs = '';
|
||||
if (count($m_aTabs) > 0)
|
||||
{
|
||||
$sTabs = "<!-- tabs -->\n<div id=\"tabbedContent\" class=\"light\">\n";
|
||||
$sTabs .= "<ul>\n";
|
||||
// Display the unordered list that will be rendered as the tabs
|
||||
$i = 0;
|
||||
foreach($m_aTabs as $sTabName => $sTabContent)
|
||||
{
|
||||
$sTabs .= "<li><a href=\"#fragment_$i\" class=\"tab\"><span>".htmlentities($sTabName)."</span></a></li>\n";
|
||||
$i++;
|
||||
}
|
||||
$sTabs .= "</ul>\n";
|
||||
// Now add the content of the tabs themselves
|
||||
$i = 0;
|
||||
foreach($m_aTabs as $sTabName => $sTabContent)
|
||||
{
|
||||
$sTabs .= "<div id=\"fragment_$i\">".$sTabContent."</div>\n";
|
||||
$i++;
|
||||
}
|
||||
$sTabs .= "</div>\n<!-- end of tabs-->\n";
|
||||
}
|
||||
$this->s_content = str_replace("\$Tabs:$sTabContainerName\$", $sTabs, $this->s_content);
|
||||
}
|
||||
|
||||
// Display the page's content
|
||||
echo $this->s_content;
|
||||
|
||||
// Add the captured output
|
||||
if (trim($s_captured_output) != "")
|
||||
{
|
||||
echo "<div class=\"raw_output\">$s_captured_output</div>\n";
|
||||
}
|
||||
echo $this->s_deferred_content;
|
||||
echo "<div class=\"jqmWindow\" id=\"ex2\">Please wait...</div>\n"; // jqModal Window
|
||||
echo "</div> <!-- RightPane -->\n";
|
||||
echo "</div> <!-- Splitter -->\n";
|
||||
echo "<div class=\"jqmWindow\" id=\"ModalDlg\"></div>";
|
||||
echo "</body>\n";
|
||||
echo "</html>\n";
|
||||
}
|
||||
|
||||
public function AddTabContainer($sTabContainer)
|
||||
{
|
||||
$this->m_aTabs[$sTabContainer] = array();
|
||||
$this->add("\$Tabs:$sTabContainer\$");
|
||||
}
|
||||
|
||||
public function AddToTab($sTabContainer, $sTabLabel, $sHtml)
|
||||
{
|
||||
if (!isset($this->m_aTabs[$sTabContainer][$sTabLabel]))
|
||||
{
|
||||
// Set the content of the tab
|
||||
$this->m_aTabs[$sTabContainer][$sTabLabel] = $sHtml;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Append to the content of the tab
|
||||
$this->m_aTabs[$sTabContainer][$sTabLabel] .= $sHtml;
|
||||
}
|
||||
}
|
||||
|
||||
public function SetCurrentTabContainer($sTabContainer = '')
|
||||
{
|
||||
$sPreviousTabContainer = $this->m_sCurrentTabContainer;
|
||||
$this->m_sCurrentTabContainer = $sTabContainer;
|
||||
return $sPreviousTabContainer;
|
||||
}
|
||||
|
||||
public function SetCurrentTab($sTabLabel = '')
|
||||
{
|
||||
$sPreviousTab = $this->m_sCurrentTab;
|
||||
$this->m_sCurrentTab = $sTabLabel;
|
||||
return $sPreviousTab;
|
||||
}
|
||||
|
||||
public function StartCollapsibleSection($sSectionLabel, $bOpen = false)
|
||||
{
|
||||
$this->add($this->GetStartCollapsibleSection($sSectionLabel, $bOpen));
|
||||
}
|
||||
|
||||
public function GetStartCollapsibleSection($sSectionLabel, $bOpen = false)
|
||||
{
|
||||
$sHtml = '';
|
||||
static $iSectionId = 0;
|
||||
$sImgStyle = $bOpen ? ' open' : '';
|
||||
$sHtml .= "<a id=\"LnkCollapse_$iSectionId\" class=\"CollapsibleLabel{$sImgStyle}\" href=\"#\">$sSectionLabel</a></br>\n";
|
||||
$sStyle = $bOpen ? '' : 'style="display:none" ';
|
||||
$sHtml .= "<div id=\"Collapse_$iSectionId\" $sStyle>";
|
||||
$this->add_ready_script("\$(\"#LnkCollapse_$iSectionId\").click(function() {\$(\"#Collapse_$iSectionId\").slideToggle('normal'); $(\"#LnkCollapse_$iSectionId\").toggleClass('open');});");
|
||||
//$this->add_ready_script("$('#LnkCollapse_$iSectionId').hide();");
|
||||
$iSectionId++;
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
public function EndCollapsibleSection()
|
||||
{
|
||||
$this->add($this->GetEndCollapsibleSection());
|
||||
}
|
||||
|
||||
public function GetEndCollapsibleSection()
|
||||
{
|
||||
return "</div>";
|
||||
}
|
||||
|
||||
public function add($sHtml)
|
||||
{
|
||||
if (!empty($this->m_sCurrentTabContainer) && !empty($this->m_sCurrentTab))
|
||||
{
|
||||
$this->AddToTab($this->m_sCurrentTabContainer, $this->m_sCurrentTab, $sHtml);
|
||||
}
|
||||
else
|
||||
{
|
||||
parent::add($sHtml);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public function AddSearchForm($sClassName, $bOpen = false)
|
||||
{
|
||||
$iSearchSectionId = 0;
|
||||
|
||||
$sStyle = $bOpen ? 'SearchDrawer' : 'SearchDrawer DrawerClosed';
|
||||
$this->add("<div id=\"Search_$iSearchSectionId\" class=\"$sStyle\">\n");
|
||||
$this->add("<h1>Search form for ".Metamodel::GetName($sClassName)."</h1>\n");
|
||||
$this->add_ready_script("\$(\"#LnkSearch_$iSearchSectionId\").click(function() {\$(\"#Search_$iSearchSectionId\").slideToggle('normal'); $(\"#LnkSearch_$iSearchSectionId\").toggleClass('open');});");
|
||||
$oFilter = new DBObjectSearch($sClassName);
|
||||
$sFilter = $oFilter->serialize();
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
cmdbAbstractObject::DisplaySearchForm($this, $oSet, array('operation' => 'search', 'filter' => $sFilter, 'search_form' => true));
|
||||
$this->add("</div>\n");
|
||||
$this->add("<div class=\"HRDrawer\"/></div>\n");
|
||||
$this->add("<div id=\"LnkSearch_$iSearchSectionId\" class=\"DrawerHandle\">Search</div>\n");
|
||||
|
||||
|
||||
$iSearchSectionId++;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
?>
|
||||
32
application/itopwizardwebpage.class.inc.php
Normal file
32
application/itopwizardwebpage.class.inc.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
require_once('itopwebpage.class.inc.php');
|
||||
/**
|
||||
* Web page to display a wizard in the iTop framework
|
||||
*/
|
||||
class iTopWizardWebPage extends iTopWebPage
|
||||
{
|
||||
var $m_iCurrentStep;
|
||||
var $m_aSteps;
|
||||
public function __construct($sTitle, $currentOrganization, $iCurrentStep, $aSteps)
|
||||
{
|
||||
parent::__construct($sTitle." - step $iCurrentStep of ".count($aSteps)." - ".$aSteps[$iCurrentStep - 1], $currentOrganization);
|
||||
$this->m_iCurrentStep = $iCurrentStep;
|
||||
$this->m_aSteps = $aSteps;
|
||||
}
|
||||
|
||||
public function output()
|
||||
{
|
||||
$aSteps = array();
|
||||
$iIndex = 0;
|
||||
foreach($this->m_aSteps as $sStepTitle)
|
||||
{
|
||||
$iIndex++;
|
||||
$sStyle = ($iIndex == $this->m_iCurrentStep) ? 'wizActiveStep' : 'wizStep';
|
||||
$aSteps[] = "<div class=\"$sStyle\"><span>$sStepTitle</span></div>";
|
||||
}
|
||||
$sWizardHeader = "<div class=\"wizHeader\"><h1>{$this->s_title}</h1>\n".implode("<div class=\"wizSeparator\"><img align=\"bottom\" src=\"../images/wizArrow.gif\"></div>", $aSteps)."<br style=\"clear:both;\"/></div>\n";
|
||||
$this->s_content = "$sWizardHeader<div class=\"wizContainer\">".$this->s_content."</div>";
|
||||
parent::output();
|
||||
}
|
||||
}
|
||||
?>
|
||||
126
application/loginwebpage.class.inc.php
Normal file
126
application/loginwebpage.class.inc.php
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
require_once("../application/nicewebpage.class.inc.php");
|
||||
/**
|
||||
* Web page used for displaying the login form
|
||||
*/
|
||||
class LoginWebPage extends NiceWebPage
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct("iTop Login");
|
||||
$this->add_style("
|
||||
body {
|
||||
background-color: #eee;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#login {
|
||||
width: 230px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 150px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #83b217;
|
||||
font-size: 16pt;
|
||||
}
|
||||
.v-spacer {
|
||||
padding-top: 1em;
|
||||
}
|
||||
");
|
||||
}
|
||||
|
||||
public function DisplayLoginForm($bFailedLogin = false)
|
||||
{
|
||||
$sAuthUser = utils::ReadParam('auth_user', '');
|
||||
$sAuthPwd = utils::ReadParam('suggest_pwd', '');
|
||||
|
||||
$this->add("<div id=\"login\">\n");
|
||||
$this->add("<h1>Welcome to iTop!</h1>\n");
|
||||
if ($bFailedLogin)
|
||||
{
|
||||
$this->add("<p class=\"hilite\">Incorrect login/password, please try again.</p>\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->add("<p>Please identify yourself before continuing.</p>\n");
|
||||
}
|
||||
$this->add("<form method=\"post\">\n");
|
||||
$this->add("<table>\n");
|
||||
$this->add("<tr><td><label for=\"user\">User Name:</label></td><td><input id=\"user\" type=\"text\" name=\"auth_user\" value=\"$sAuthUser\" /></td></tr>\n");
|
||||
$this->add("<tr><td><label for=\"pwd\">Password:</label></td><td><input id=\"pwd\" type=\"password\" name=\"auth_pwd\" value=\"$sAuthPwd\" /></td></tr>\n");
|
||||
$this->add("<tr><td colspan=\"2\" class=\"center v-spacer\"> <input type=\"submit\" value=\"Enter iTop\" /></td></tr>\n");
|
||||
$this->add("</table>\n");
|
||||
$this->add("<input type=\"hidden\" name=\"loginop\" value=\"login\" />\n");
|
||||
$this->add("</form>\n");
|
||||
$this->add("</div>\n");
|
||||
}
|
||||
|
||||
static protected function ResetSession()
|
||||
{
|
||||
// Unset all of the session variables.
|
||||
$_SESSION = array();
|
||||
// If it's desired to kill the session, also delete the session cookie.
|
||||
// Note: This will destroy the session, and not just the session data!
|
||||
if (isset($_COOKIE[session_name()]))
|
||||
{
|
||||
setcookie(session_name(), '', time()-3600, '/');
|
||||
}
|
||||
// Finally, destroy the session.
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
static function DoLogin()
|
||||
{
|
||||
$operation = utils::ReadParam('loginop', '');
|
||||
session_start();
|
||||
|
||||
if ($operation == 'logoff')
|
||||
{
|
||||
self::ResetSession();
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['auth_user']) || !isset($_SESSION['auth_pwd']))
|
||||
{
|
||||
if ($operation == 'login')
|
||||
{
|
||||
$sAuthUser = utils::ReadParam('auth_user', '', 'post');
|
||||
$sAuthPwd = utils::ReadParam('auth_pwd', '', 'post');
|
||||
}
|
||||
else
|
||||
{
|
||||
$oPage = new LoginWebPage();
|
||||
$oPage->DisplayLoginForm();
|
||||
$oPage->output();
|
||||
exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sAuthUser = $_SESSION['auth_user'];
|
||||
$sAuthPwd = $_SESSION['auth_pwd'];
|
||||
}
|
||||
if (!UserRights::Login($sAuthUser, $sAuthPwd))
|
||||
{
|
||||
self::ResetSession();
|
||||
$oPage = new LoginWebPage();
|
||||
$oPage->DisplayLoginForm( true /* failed attempt */);
|
||||
$oPage->output();
|
||||
exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
$_SESSION['auth_user'] = $sAuthUser ;
|
||||
$_SESSION['auth_pwd'] = $sAuthPwd;
|
||||
|
||||
}
|
||||
}
|
||||
} // End of class
|
||||
?>
|
||||
215
application/menunode.class.inc.php
Normal file
215
application/menunode.class.inc.php
Normal file
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
require_once('../core/attributedef.class.inc.php');
|
||||
require_once('../core/filterdef.class.inc.php');
|
||||
require_once('../core/stimulus.class.inc.php');
|
||||
require_once('../core/MyHelpers.class.inc.php');
|
||||
|
||||
require_once('../core/cmdbsource.class.inc.php');
|
||||
require_once('../core/sqlquery.class.inc.php');
|
||||
|
||||
require_once('../core/dbobject.class.php');
|
||||
require_once('../core/dbobjectsearch.class.php');
|
||||
require_once('../core/dbobjectset.class.php');
|
||||
|
||||
require_once('../application/displayblock.class.inc.php');
|
||||
|
||||
/**
|
||||
* This class manages en entries in the menu tree on the left of the iTop pages
|
||||
*/
|
||||
class menuNode extends DBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "gui",
|
||||
"name" => "menuNode",
|
||||
"description" => "Main menu configuration elements",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_menunode",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
// MetaModel::Init_AddAttribute(new AttributeExternalKey("change", array("label"=>"change", "description"=>"change", "allowed_values"=>null, "sql"=>"changeid", "targetclass"=>"CMDBChange", "jointype"=>"closed")));
|
||||
// MetaModel::Init_AddAttribute(new AttributeExternalField("date", array("label"=>"date", "description"=>"date and time of the change", "allowed_values"=>null, "extkey_attcode"=>"change", "target_attcode"=>"date")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Menu Name", "description"=>"Short name for this menu", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("label", array("label"=>"Menu Description", "description"=>"Long description for this menu", "allowed_values"=>null, "sql"=>"label", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("hyperlink", array("label"=>"Hyperlink", "description"=>"Hyperlink to the page", "allowed_values"=>null, "sql"=>"hyperlink", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("icon_path", array("label"=>"Menu Icon", "description"=>"Path to the icon o the menu", "allowed_values"=>null, "sql"=>"icon_path", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("template", array("label"=>"Template", "description"=>"HTML template for the view", "allowed_values"=>null, "sql"=>"template", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("type", array("label"=>"Type", "description"=>"Type of menu", "allowed_values"=>new ValueSetEnum('application,user,administrator'), "sql"=>"type", "default_value"=>"application", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("rank", array("label"=>"Display rank", "description"=>"Sort order for displaying the menu", "allowed_values"=>null, "sql"=>"rank", "default_value" => 999, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("parent_id", array("label"=>"Parent Menu Item", "description"=>"Parent Menu Item", "allowed_values"=>null, "sql"=>"parent_id", "targetclass"=>"menuNode", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("parent_name", array("label"=>"Parent Menu Item", "description"=>"Parent Menu Item", "allowed_values"=>null, "extkey_attcode"=>"parent_id", "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("user_id", array("label"=>"Owner of the menu", "description"=>"User who owns this menu (for user defined menus)", "allowed_values"=>null, "sql"=>"user_id", "default_value" => 0, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("label");
|
||||
MetaModel::Init_AddFilterFromAttribute("parent_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("rank");
|
||||
MetaModel::Init_AddFilterFromAttribute("type");
|
||||
MetaModel::Init_AddFilterFromAttribute("user_id");
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('parent_id', 'name', 'label', 'hyperlink', 'template', 'rank', 'type')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('parent_id', 'name', 'label', 'rank', 'type')); // Attributes to be displayed for a list
|
||||
}
|
||||
|
||||
public function IsVisible()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function GetMenuName()
|
||||
{
|
||||
return $this->Get('name');
|
||||
}
|
||||
|
||||
public function GetMenuIcon()
|
||||
{
|
||||
return $this->Get('icon_path');
|
||||
}
|
||||
|
||||
public function GetMenuLabel()
|
||||
{
|
||||
return $this->Get('label');
|
||||
}
|
||||
|
||||
public function GetMenuLink($aExtraParams)
|
||||
{
|
||||
$aExtraParams['menu'] = $this->GetKey(); // Make sure we overwrite the current menu id (if any)
|
||||
$aParams = array();
|
||||
foreach($aExtraParams as $sName => $sValue)
|
||||
{
|
||||
$aParams[] = urlencode($sName)."=".urlencode($sValue);
|
||||
}
|
||||
return $this->Get('hyperlink')."?".implode("&", $aParams);
|
||||
}
|
||||
|
||||
public function GetChildNodesSet($sType = null)
|
||||
{
|
||||
$aParams = array();
|
||||
|
||||
if ($sType == 'user')
|
||||
{
|
||||
$sSelectChilds = 'SELECT menuNode AS m WHERE m.parent_id = :parent AND type = :type AND m.user_id = :user';
|
||||
$aParams = array('parent' => $this->GetKey(), 'type' => $sType, 'user' => UserRights::GetUserId());
|
||||
}
|
||||
elseif ($sType != null)
|
||||
{
|
||||
$sSelectChilds = 'SELECT menuNode AS m WHERE m.parent_id = :parent AND type = :type';
|
||||
$aParams = array('parent' => $this->GetKey(), 'type' => $sType);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSelectChilds = 'SELECT menuNode AS m WHERE m.parent_id = :parent';
|
||||
$aParams = array('parent' => $this->GetKey());
|
||||
}
|
||||
$oSearchFilter = DBObjectSearch::FromOQL($sSelectChilds);
|
||||
$oSet = new CMDBObjectSet($oSearchFilter, array('rank' => true), $aParams);
|
||||
return $oSet;
|
||||
}
|
||||
|
||||
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
||||
{
|
||||
$sTemplate = $this->Get('template');
|
||||
$oTemplate = new DisplayTemplate($sTemplate);
|
||||
$oTemplate->Render($oPage, $aExtraParams);
|
||||
//$this->ProcessTemplate($sTemplate, $oPage, $aExtraParams);
|
||||
}
|
||||
|
||||
public function DisplayMenu(iTopWebPage $oP, $sType, $aExtraParams)
|
||||
{
|
||||
$oP->AddToMenu("<li><a href=\"".$this->GetMenuLink($aExtraParams)."\" title=\"".$this->GetMenuLabel()."\">".$this->GetMenuName()."</a>");
|
||||
$oSet = $this->GetChildNodesSet($sType);
|
||||
if ($oSet->Count() > 0)
|
||||
{
|
||||
$oP->AddToMenu("\n<ul>\n");
|
||||
while($oChildNode = $oSet->Fetch())
|
||||
{
|
||||
$oChildNode->DisplayMenu($oP, $sType, $aExtraParams);
|
||||
}
|
||||
$oP->AddToMenu("</ul>\n");
|
||||
}
|
||||
$oP->AddToMenu("</li>\n");
|
||||
}
|
||||
static public function DisplayCreationForm(WebPage $oP, $sClass, $sFilter, $aExtraParams = array())
|
||||
{
|
||||
$oFilter = DBObjectSearch::unserialize($sFilter);
|
||||
$oP->p('Create a new menu item for: '.$oFilter->__DescribeHTML());
|
||||
$oP->add('<form action="UniversalSearch.php" method="post">');
|
||||
$oP->add('<input type="hidden" name="operation" value="add_menu">');
|
||||
$oP->add('<input type="hidden" name="filter" value="'.$sFilter.'">');
|
||||
$oP->add('<input type="hidden" name="class" value="'.$sClass.'">');
|
||||
$oP->p('Menu Label: <input type="text" name="label" size="30">');
|
||||
$oP->p('Description: <input type="text" name="description" size="30">');
|
||||
$oP->add('<p>Insert after: <select name="previous_node_id">');
|
||||
$aNodes = self::GetMenuAsArray(null, 'user');
|
||||
foreach($aNodes as $aNodeDesc)
|
||||
{
|
||||
$oP->add('<option value="'.$aNodeDesc['id'].'">'.str_repeat(' ', $aNodeDesc['depth']).$aNodeDesc['label'].'</option>');
|
||||
}
|
||||
$oP->add('</select></p>');
|
||||
$oP->p('<input type="checkbox" name="child_item" value="1"> Create as a child menu item');
|
||||
$oP->p('<input type="submit" value=" Ok "> <input type="button" class="jqmClose" value="Cancel">');
|
||||
$oP->add('</form>');
|
||||
}
|
||||
|
||||
static public function GetMenuAsArray($oRootNode = null, $sType = 'application', $iDepth = 0)
|
||||
{
|
||||
$aNodes = array();
|
||||
if (is_object($oRootNode))
|
||||
{
|
||||
$oChildSet = $oRootNode->GetChildNodesSet($sType);
|
||||
while($oNode = $oChildSet->Fetch())
|
||||
{
|
||||
$aNodes[] = array('depth' => $iDepth, 'id' => $oNode->GetKey(), 'label' => $oNode->GetName());
|
||||
$aNodes = array_merge($aNodes, self::GetMenuAsArray($oNode, $sType, $iDepth+1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSearchFilter = new DbObjectSearch("menuNode");
|
||||
$oSearchFilter->AddCondition('parent_id', 0, '=');
|
||||
if ($sType != null)
|
||||
{
|
||||
$oSearchFilter->AddCondition('type', $sType, '=');
|
||||
if ($sType == 'user')
|
||||
{
|
||||
$oSearchFilter->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||
}
|
||||
}
|
||||
$oRootSet = new CMDBObjectSet($oSearchFilter, array('rank' => true));
|
||||
while($oNode = $oRootSet->Fetch())
|
||||
{
|
||||
$aNodes[] = array('depth' => $iDepth, 'id' => $oNode->GetKey(), 'label' => $oNode->GetName());
|
||||
$aNodes = array_merge($aNodes, self::GetMenuAsArray($oNode, $sType, $iDepth+1));
|
||||
}
|
||||
}
|
||||
return $aNodes;
|
||||
}
|
||||
/**
|
||||
* Returns a set of all the nodes following the current node in the tree
|
||||
* (i.e. nodes with the same parent but with a greater rank)
|
||||
*/
|
||||
public function GetNextNodesSet($sType = 'application')
|
||||
{
|
||||
$oSearchFilter = new DBObjectSearch("menuNode");
|
||||
$oSearchFilter->AddCondition('parent_id', $this->Get('parent_id'));
|
||||
$oSearchFilter->AddCondition('rank', $this->Get('rank'), '>');
|
||||
if ($sType != null)
|
||||
{
|
||||
$oSearchFilter->AddCondition('type', $sType, '=');
|
||||
if ($sType == 'user')
|
||||
{
|
||||
$oSearchFilter->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||
}
|
||||
}
|
||||
$oSet = new DBObjectSet($oSearchFilter, array('rank'=> true)); // Order by rank (true means ascending)
|
||||
return $oSet;
|
||||
}
|
||||
}
|
||||
?>
|
||||
79
application/nicewebpage.class.inc.php
Normal file
79
application/nicewebpage.class.inc.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
require_once("../application/webpage.class.inc.php");
|
||||
/**
|
||||
* Web page with some associated CSS and scripts (jquery) for a fancier display
|
||||
*/
|
||||
class NiceWebPage extends WebPage
|
||||
{
|
||||
var $m_aReadyScripts;
|
||||
|
||||
public function __construct($s_title)
|
||||
{
|
||||
parent::__construct($s_title);
|
||||
$this->m_aReadyScripts = array();
|
||||
$this->add_linked_script("../js/jquery.latest.js");
|
||||
$this->add_linked_script("../js/jquery.history_remote.pack.js");
|
||||
//$this->add_linked_script("../js/ui.resizable.js");
|
||||
$this->add_linked_script("../js/ui.tabs.js");
|
||||
$this->add_linked_script("../js/hovertip.js");
|
||||
$this->add_linked_script("../js/jqModal.js");
|
||||
$this->add_linked_stylesheet("../css/light-grey.css");
|
||||
$this->add_linked_stylesheet("../js/themes/light/light.tabs.css");
|
||||
//$this->add_linked_stylesheet("../css/jquery.tabs-ie.css", "lte IE 7");
|
||||
$this->add_linked_stylesheet("../css/jqModal.css");
|
||||
$this->add_ready_script(' window.setTimeout(hovertipInit, 1);');
|
||||
}
|
||||
|
||||
public function small_p($sText)
|
||||
{
|
||||
$this->add("<p style=\"font-size:smaller\">$sText</p>\n");
|
||||
}
|
||||
|
||||
// By Rom, used by CSVImport and Advanced search
|
||||
public function MakeClassesSelect($sName, $sDefaultValue, $iWidthPx, $iActionCode = null)
|
||||
{
|
||||
// $aTopLevelClasses = array('bizService', 'bizContact', 'logInfra', 'bizDocument');
|
||||
// These are classes wich root class is cmdbAbstractObject !
|
||||
$this->add("<select id=\"select_$sName\" name=\"$sName\">");
|
||||
foreach(MetaModel::GetClasses('bizmodel') as $sClassName)
|
||||
{
|
||||
if (is_null($iActionCode) || UserRights::IsActionAllowed($sClassName, $iActionCode))
|
||||
{
|
||||
$sSelected = ($sClassName == $sDefaultValue) ? " SELECTED" : "";
|
||||
$this->add("<option style=\"width: ".$iWidthPx." px;\" value=\"$sClassName\"$sSelected>$sClassName - ".MetaModel::GetClassDescription($sClassName)."</option>");
|
||||
}
|
||||
}
|
||||
$this->add("</select>");
|
||||
}
|
||||
|
||||
// By Rom, used by Advanced search
|
||||
public function add_select($aChoices, $sName, $sDefaultValue, $iWidthPx)
|
||||
{
|
||||
$this->add("<select id=\"select_$sName\" name=\"$sName\">");
|
||||
foreach($aChoices as $sKey => $sValue)
|
||||
{
|
||||
$sSelected = ($sKey == $sDefaultValue) ? " SELECTED" : "";
|
||||
$this->add("<option style=\"width: ".$iWidthPx." px;\" value=\"$sKey\"$sSelected>$sValue</option>");
|
||||
}
|
||||
$this->add("</select>");
|
||||
}
|
||||
|
||||
public function add_ready_script($sScript)
|
||||
{
|
||||
$this->m_aReadyScripts[] = $sScript;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs (via some echo) the complete HTML page by assembling all its elements
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
if (count($this->m_aReadyScripts)>0)
|
||||
{
|
||||
$this->add_script("\$(document).ready(function() {\n".implode("\n", $this->m_aReadyScripts)."\n});");
|
||||
}
|
||||
parent::output();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
10
application/startup.inc.php
Normal file
10
application/startup.inc.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
define('ITOP_VERSION', '0.9');
|
||||
define('ITOP_REVISION', '$WCREV$');
|
||||
define('ITOP_BUILD_DATE', '$WCNOW$');
|
||||
|
||||
require_once('../application/utils.inc.php');
|
||||
|
||||
MetaModel::Startup(ITOP_CONFIG_FILE);
|
||||
|
||||
?>
|
||||
200
application/template.class.inc.php
Normal file
200
application/template.class.inc.php
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
require_once('../application/displayblock.class.inc.php');
|
||||
/**
|
||||
* This class manages the special template format used internally to build the iTop web pages
|
||||
*/
|
||||
class DisplayTemplate
|
||||
{
|
||||
protected $m_sTemplate;
|
||||
protected $m_aTags;
|
||||
static protected $iBlockCount = 0;
|
||||
|
||||
public function __construct($sTemplate)
|
||||
{
|
||||
$this->m_aTags = array('itopblock', 'itoptabs', 'itoptab', 'itoptoggle');
|
||||
$this->m_sTemplate = $sTemplate;
|
||||
}
|
||||
|
||||
public function Render(WebPage $oPage, $aParams = array())
|
||||
{
|
||||
$this->m_sTemplate = MetaModel::ApplyParams($this->m_sTemplate, $aParams);
|
||||
$iStart = 0;
|
||||
$iEnd = strlen($this->m_sTemplate);
|
||||
$iCount = 0;
|
||||
$iBeforeTagPos = $iStart;
|
||||
$iAfterTagPos = $iStart;
|
||||
while($sTag = $this->GetNextTag($iStart, $iEnd))
|
||||
{
|
||||
$sContent = $this->GetTagContent($sTag, $iStart, $iEnd);
|
||||
$iAfterTagPos = $iEnd + strlen('</'.$sTag.'>');
|
||||
$sOuterTag = substr($this->m_sTemplate, $iStart, $iAfterTagPos - $iStart);
|
||||
$oPage->add(substr($this->m_sTemplate, $iBeforeTagPos, $iStart - $iBeforeTagPos));
|
||||
if ($sTag == DisplayBlock::TAG_BLOCK)
|
||||
{
|
||||
$oBlock = DisplayBlock::FromTemplate($sOuterTag);
|
||||
if (is_object($oBlock))
|
||||
{
|
||||
$oBlock->Display($oPage, 'block_'.self::$iBlockCount, $aParams);
|
||||
}
|
||||
self::$iBlockCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aAttributes = $this->GetTagAttributes($sTag, $iStart, $iEnd);
|
||||
//$oPage->p("Tag: $sTag - ($iStart, $iEnd)");
|
||||
$this->RenderTag($oPage, $sTag, $aAttributes, $sContent);
|
||||
|
||||
}
|
||||
$iAfterTagPos = $iEnd + strlen('</'.$sTag.'>');
|
||||
$iBeforeTagPos = $iAfterTagPos;
|
||||
$iStart = $iEnd;
|
||||
$iEnd = strlen($this->m_sTemplate);
|
||||
$iCount++;
|
||||
if ($iCount > 10) break; //@@@ Why ?? Debug ??
|
||||
}
|
||||
$oPage->add(substr($this->m_sTemplate, $iAfterTagPos));
|
||||
}
|
||||
|
||||
public function GetNextTag(&$iStartPos, &$iEndPos)
|
||||
{
|
||||
$iChunkStartPos = $iStartPos;
|
||||
$sNextTag = null;
|
||||
$iStartPos = $iEndPos;
|
||||
foreach($this->m_aTags as $sTag)
|
||||
{
|
||||
// Search for the opening tag
|
||||
$iOpeningPos = stripos($this->m_sTemplate, '<'.$sTag.' ', $iChunkStartPos);
|
||||
if ($iOpeningPos === false)
|
||||
{
|
||||
$iOpeningPos = stripos($this->m_sTemplate, '<'.$sTag.'>', $iChunkStartPos);
|
||||
}
|
||||
if ($iOpeningPos !== false)
|
||||
{
|
||||
$iClosingPos = stripos($this->m_sTemplate, '</'.$sTag.'>', $iOpeningPos);
|
||||
}
|
||||
if ( ($iOpeningPos !== false) && ($iClosingPos !== false))
|
||||
{
|
||||
if ($iOpeningPos < $iStartPos)
|
||||
{
|
||||
// This is the next tag
|
||||
$iStartPos = $iOpeningPos;
|
||||
$iEndPos = $iClosingPos;
|
||||
$sNextTag = $sTag;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $sNextTag;
|
||||
}
|
||||
|
||||
public function GetTagContent($sTag, $iStartPos, $iEndPos)
|
||||
{
|
||||
$sContent = "";
|
||||
$iContentStart = strpos($this->m_sTemplate, '>', $iStartPos); // Content of tag start immediatly after the first closing bracket
|
||||
if ($iContentStart !== false)
|
||||
{
|
||||
$sContent = substr($this->m_sTemplate, 1+$iContentStart, $iEndPos - $iContentStart - 1);
|
||||
}
|
||||
return $sContent;
|
||||
}
|
||||
|
||||
public function GetTagAttributes($sTag, $iStartPos, $iEndPos)
|
||||
{
|
||||
$aAttr = array();
|
||||
$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
|
||||
if ( ($iAttrStart !== false) && ($iAttrEnd !== false) && ($iAttrEnd > $iAttrStart))
|
||||
{
|
||||
$sAttributes = substr($this->m_sTemplate, 1+$iAttrStart, $iAttrEnd - $iAttrStart - 1);
|
||||
$aAttributes = explode(' ', $sAttributes);
|
||||
foreach($aAttributes as $sAttr)
|
||||
{
|
||||
if ( preg_match('/(.+) *= *"(.+)"$/', $sAttr, $aMatches) )
|
||||
{
|
||||
$aAttr[strtolower($aMatches[1])] = $aMatches[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aAttr;
|
||||
}
|
||||
|
||||
protected function RenderTag($oPage, $sTag, $aAttributes, $sContent)
|
||||
{
|
||||
static $iTabContainerCount = 0;
|
||||
switch($sTag)
|
||||
{
|
||||
case 'itoptabs':
|
||||
$oPage->AddTabContainer('Tabs_'.$iTabContainerCount);
|
||||
$oPage->SetCurrentTabContainer('Tabs_'.$iTabContainerCount);
|
||||
$iTabContainerCount++;
|
||||
//$oPage->p('Content:<pre>'.htmlentities($sContent).'</pre>');
|
||||
$oTemplate = new DisplayTemplate($sContent);
|
||||
$oTemplate->Render($oPage, array()); // no params to apply, they have already been applied
|
||||
$oPage->SetCurrentTabContainer('');
|
||||
break;
|
||||
|
||||
case 'itoptab':
|
||||
$oPage->SetCurrentTab(str_replace('_', ' ', $aAttributes['name']));
|
||||
$oTemplate = new DisplayTemplate($sContent);
|
||||
$oTemplate->Render($oPage, array()); // no params to apply, they have already been applied
|
||||
//$oPage->p('iTop Tab Content:<pre>'.htmlentities($sContent).'</pre>');
|
||||
$oPage->SetCurrentTab('');
|
||||
break;
|
||||
|
||||
case 'itoptoggle':
|
||||
$sName = isset($aAttributes['name']) ? $aAttributes['name'] : 'Tagada';
|
||||
$bOpen = isset($aAttributes['open']) ? $aAttributes['open'] : true;
|
||||
$oPage->StartCollapsibleSection($sName, $bOpen);
|
||||
$oTemplate = new DisplayTemplate($sContent);
|
||||
$oTemplate->Render($oPage, array()); // no params to apply, they have already been applied
|
||||
//$oPage->p('iTop Tab Content:<pre>'.htmlentities($sContent).'</pre>');
|
||||
$oPage->EndCollapsibleSection();
|
||||
break;
|
||||
|
||||
case 'itopblock': // No longer used, handled by DisplayBlock::FromTemplate see above
|
||||
$oPage->add("<!-- Application Error: should be handled by DisplayBlock::FromTemplate -->");
|
||||
break;
|
||||
|
||||
default:
|
||||
// Unknown tag, just ignore it or now -- output an HTML comment
|
||||
$oPage->add("<!-- unsupported tag: $sTag -->");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit test
|
||||
*/
|
||||
static public function UnitTest()
|
||||
{
|
||||
require_once('../application/startup.inc.php');
|
||||
require_once("../application/itopwebpage.class.inc.php");
|
||||
|
||||
$sTemplate = '<div class="page_header">
|
||||
<div class="actions_details"><a href="#"><span>Actions</span></a></div>
|
||||
<h1>$class$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = \'$class$\'</itopblock>
|
||||
</div>
|
||||
<img src="../../images/connect_to_network.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/sibusql">bizNetworkDevice: pkey = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Interfaces">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/sibusql">bizInterface: device_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Contacts">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/sibusql">bizContact: PKEY IS contact_id IN (ContactsLinks: object_id = $pkey$)</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/sibusql">bizDocument: PKEY IS doc_id IN (lnkDocumentRealObject: object_id = $pkey$)</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>';
|
||||
|
||||
$oPage = new iTopWebPage('Unit Test', 3);
|
||||
//$oPage->add("Template content: <pre>".htmlentities($sTemplate)."</pre>\n");
|
||||
$oTemplate = new DisplayTemplate($sTemplate);
|
||||
$oTemplate->Render($oPage, array('class'=>'Network device','pkey'=> 271, 'name' => 'deliversw01.mecanorama.fr', 'org_id' => 3));
|
||||
$oPage->output();
|
||||
}
|
||||
}
|
||||
|
||||
//DisplayTemplate::UnitTest();
|
||||
|
||||
?>
|
||||
12
application/templates/audit_category.html
Normal file
12
application/templates/audit_category.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/sibusql" label="Actions">$class$: pkey = $pkey$</itopblock>
|
||||
<h1>$class$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../../images/clean.png" style="margin-top:-20px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/sibusql">$class$: pkey = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Rules">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/sibusql">AuditRule: category_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
330
application/ui.linkswidget.class.inc.php
Normal file
330
application/ui.linkswidget.class.inc.php
Normal file
@@ -0,0 +1,330 @@
|
||||
<?php
|
||||
require_once('../application/webpage.class.inc.php');
|
||||
require_once('../application/displayblock.class.inc.php');
|
||||
|
||||
class UILinksWidget
|
||||
{
|
||||
protected $m_sClass;
|
||||
protected $m_sAttCode;
|
||||
protected $m_sNameSuffix;
|
||||
protected $m_iInputId;
|
||||
|
||||
public function __construct($sClass, $sAttCode, $iInputId, $sNameSuffix = '')
|
||||
{
|
||||
$this->m_sClass = $sClass;
|
||||
$this->m_sAttCode = $sAttCode;
|
||||
$this->m_sNameSuffix = $sNameSuffix;
|
||||
$this->m_iInputId = $iInputId;
|
||||
}
|
||||
|
||||
public function Display(WebPage $oPage, $oCurrentValuesSet = null)
|
||||
{
|
||||
$sHTMLValue = '';
|
||||
$sTargetClass = self::GetTargetClass($this->m_sClass, $this->m_sAttCode);
|
||||
// #@# todo - add context information, otherwise any value will be authorized for external keys
|
||||
$aAllowedValues = MetaModel::GetAllowedValues_att($this->m_sClass, $this->m_sAttCode, array(), '');
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sAttCode);
|
||||
$sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
|
||||
$sExtKeyToMe = $oAttDef->GetExtKeyToMe();
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode($this->m_sClass);
|
||||
$sDefaultState = MetaModel::GetDefaultState($this->m_sClass);
|
||||
|
||||
$aAttributes = array();
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
foreach(MetaModel::ListAttributeDefs($sLinkedClass) as $sAttCode=>$oAttDef)
|
||||
{
|
||||
if ($sStateAttCode == $sAttCode)
|
||||
{
|
||||
// State attribute is always hidden from the UI
|
||||
}
|
||||
else if (!$oAttDef->IsExternalField() && ($sAttCode != $sExtKeyToMe) && ($sAttCode != $sExtKeyToRemote))
|
||||
{
|
||||
$iFlags = MetaModel::GetAttributeFlags($this->m_sClass, $sDefaultState, $sAttCode);
|
||||
if ( !($iFlags & OPT_ATT_HIDDEN) && !($iFlags & OPT_ATT_READONLY) )
|
||||
{
|
||||
$aAttributes[] = $sAttCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
$sAttributes = "['".implode("','", $aAttributes)."']";
|
||||
if ($oCurrentValuesSet != null)
|
||||
{
|
||||
// Serialize the link set into a JSon object
|
||||
$aCurrentValues = array();
|
||||
while($oLinkObj = $oCurrentValuesSet->Fetch())
|
||||
{
|
||||
$sRow = '{';
|
||||
foreach($aAttributes as $sLinkAttCode)
|
||||
{
|
||||
$sRow.= "\"$sLinkAttCode\": \"".addslashes($oLinkObj->Get($sLinkAttCode))."\", ";
|
||||
}
|
||||
$sRow .= "\"$sExtKeyToRemote\": ".$oLinkObj->Get($sExtKeyToRemote).'}';
|
||||
$aCurrentValues[] = $sRow;
|
||||
}
|
||||
$sJSON = '['.implode(',', $aCurrentValues).']';
|
||||
}
|
||||
else
|
||||
{
|
||||
//echo "JSON VA IECH<br/>\n";
|
||||
}
|
||||
//echo "JASON: $sJSON<br/>\n";;
|
||||
|
||||
// Many values (or even a unknown list) display an autocomplete
|
||||
if ( (count($aAllowedValues) == 0) || (count($aAllowedValues) > 50) )
|
||||
{
|
||||
// too many choices, use an autocomplete
|
||||
// The input for the auto complete
|
||||
$sTitle = $oAttDef->GetDescription();
|
||||
$sHTMLValue .= "<script type=\"text/javascript\">\n";
|
||||
$sHTMLValue .= "oLinkWidget{$this->m_iInputId} = new LinksWidget('{$this->m_iInputId}', '$sLinkedClass', '$sExtKeyToMe', '$sExtKeyToRemote', $sAttributes);\n";
|
||||
$sHTMLValue .= "</script>\n";
|
||||
$oPage->add_at_the_end($this->GetObjectPickerDialog($oPage, $sTargetClass, 'oLinkWidget'.$this->m_iInputId.'.OnOk')); // Forms should not be inside forms
|
||||
$oPage->add_at_the_end($this->GetLinkObjectDialog($oPage, $this->m_iInputId)); // Forms should not be inside forms
|
||||
$sHTMLValue .= "<input type=\"text\" id=\"ac_{$this->m_iInputId}\" size=\"35\" value=\"\" title=\"Type the first 3 characters\"/>";
|
||||
$sHTMLValue .= "<input type=\"button\" id=\"ac_add_{$this->m_iInputId}\" value=\" Add... \" class=\"action\" onClick=\"oLinkWidget{$this->m_iInputId}.AddObject();\"/>";
|
||||
$sHTMLValue .= " <input type=\"button\" value=\"Browse...\" class=\"action\" onClick=\"return ManageObjects('$sTitle', '$sTargetClass', '$this->m_iInputId', '$sExtKeyToRemote');\"/>";
|
||||
// another hidden input to store & pass the object's Id
|
||||
$sHTMLValue .= "<input type=\"hidden\" id=\"id_ac_{$this->m_iInputId}\" onChange=\"EnableAddButton('{$this->m_iInputId}');\"/>\n";
|
||||
$sHTMLValue .= "<input type=\"hidden\" id=\"{$this->m_iInputId}\" name=\"attr_{$this->m_sAttCode}{$this->m_sNameSuffix}\" value=\"\"/>\n";
|
||||
$oPage->add_ready_script("\$('#{$this->m_iInputId}').val('$sJSON');\noLinkWidget{$this->m_iInputId}.Init();\n\$('#ac_{$this->m_iInputId}').autocomplete('./ajax.render.php', { scroll:true, minChars:3, onItemSelect:selectItem, onFindValue:findValue, formatItem:formatItem, autoFill:true, keyHolder:'#id_ac_{$this->m_iInputId}', extraParams:{operation:'ui.linkswidget', sclass:'{$this->m_sClass}', attCode:'{$this->m_sAttCode}', max:30}});");
|
||||
$oPage->add_ready_script("\$('#ac_add_{$this->m_iInputId}').attr('disabled', 'disabled');");
|
||||
$oPage->add_ready_script("\$('#ac_{$this->m_iInputId}').result( function(event, data, formatted) { if (data) { $('#id_ac_{$this->m_iInputId}').val(data[1]); $('#ac_add_{$this->m_iInputId}').attr('disabled', ''); } else { $('#ac_add_{$this->m_iInputId}').attr('disabled', 'disabled'); } } );");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Few choices, use a normal 'select'
|
||||
$sHTMLValue = "<select name=\"attr_{$this->m_sAttCode}\" id=\"{$this->m_iInputId}\">\n";
|
||||
$sHTMLValue .= "<option value=\"0\">--- select a value ---</option>\n";
|
||||
if (count($aAllowedValues) > 0)
|
||||
{
|
||||
foreach($aAllowedValues as $key => $value)
|
||||
{
|
||||
$sHTMLValue .= "<option value=\"$key\"$sSelected>$value</option>\n";
|
||||
}
|
||||
}
|
||||
$sHTMLValue .= "</select>\n";
|
||||
}
|
||||
$sHTMLValue .= "<div id=\"{$this->m_iInputId}_values\">\n";
|
||||
if ($oCurrentValuesSet != null)
|
||||
{
|
||||
// transform the DBObjectSet into a CMDBObjectSet !!!
|
||||
$aLinkedObjects = $oCurrentValuesSet->ToArray(false);
|
||||
// Actual values will be displayed asynchronously, no need to display them here
|
||||
//if (count($aLinkedObjects) > 0)
|
||||
//{
|
||||
// $oSet = CMDBObjectSet::FromArray($sLinkedClass, $aLinkedObjects);
|
||||
// $oDisplayBlock = DisplayBlock::FromObjectSet($oSet, 'list');
|
||||
// $sHTMLValue .= $oDisplayBlock->GetDisplay($oPage, $this->m_iInputId.'_current', array('linkage' => $sExtKeyToMe, 'menu' => false));
|
||||
//}
|
||||
}
|
||||
$sHTMLValue .= "</div>\n";
|
||||
return $sHTMLValue;
|
||||
}
|
||||
/**
|
||||
* This static function is called by the Ajax Page when there is a need to fill an autocomplete combo
|
||||
* @param $oPage WebPage The ajax page used for the put^put (sent back to the browser
|
||||
* @param $oContext UserContext The context of the user (for limiting the search)
|
||||
* @param $sClass string The name of the class of the current object being edited
|
||||
* @param $sAttCode string The name of the attribute being edited
|
||||
* @param $sName string The partial name that was typed by the user
|
||||
* @param $iMaxCount integer The maximum number of items to return
|
||||
* @return void
|
||||
*/
|
||||
static public function Autocomplete(WebPage $oPage, UserContext $oContext, $sClass, $sAttCode, $sName, $iMaxCount)
|
||||
{
|
||||
// #@# todo - add context information, otherwise any value will be authorized for external keys
|
||||
$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, array() /* $aArgs */, $sName);
|
||||
if ($aAllowedValues != null)
|
||||
{
|
||||
$iCount = $iMaxCount;
|
||||
foreach($aAllowedValues as $key => $value)
|
||||
{
|
||||
$oPage->add($value."|".$key."\n");
|
||||
$iCount--;
|
||||
if ($iCount == 0) break;
|
||||
}
|
||||
}
|
||||
else // No limitation to the allowed values
|
||||
{
|
||||
// Search for all the object of the linked class
|
||||
$oAttDef = $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
$sSearchClass = self::GetTargetClass($sClass, $sAttCode);
|
||||
$oFilter = $oContext->NewFilter($sSearchClass);
|
||||
$sSearchAttCode = MetaModel::GetNameAttributeCode($sSearchClass);
|
||||
$oFilter->AddCondition($sSearchAttCode, $sName, 'Begins with');
|
||||
$oSet = new CMDBObjectSet($oFilter, array($sSearchAttCode => true));
|
||||
$iCount = 0;
|
||||
while( ($iCount < $iMaxCount) && ($oObj = $oSet->fetch()) )
|
||||
{
|
||||
$oPage->add($oObj->GetName()."|".$oObj->GetKey()."\n");
|
||||
$iCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This static function is called by the Ajax Page display a set of objects being linked
|
||||
* to the object being created
|
||||
* @param $oPage WebPage The ajax page used for the put^put (sent back to the browser
|
||||
* @param $sClass string The name of the 'linking class' which is the class of the objects to display
|
||||
* @param $sSet JSON serialized set of objects
|
||||
* @param $sExtKeyToMe Name of the attribute in sClass that is pointing to a given object
|
||||
* @param $iObjectId The id of the object $sExtKeyToMe is pointing to
|
||||
* @return void
|
||||
*/
|
||||
static public function RenderSet($oPage, $sClass, $sJSONSet, $sExtKeyToMe, $sExtKeyToRemote, $iObjectId)
|
||||
{
|
||||
$aSet = json_decode($sJSONSet, true); // true means hash array instead of object
|
||||
$oSet = CMDBObjectSet::FromScratch($sClass);
|
||||
foreach($aSet as $aObject)
|
||||
{
|
||||
$oObj = MetaModel::NewObject($sClass);
|
||||
foreach($aObject as $sAttCode => $value)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
if ($oAttDef->IsExternalKey())
|
||||
{
|
||||
$oTargetObj = MetaModel::GetObject($oAttDef->GetTargetClass(), $value); // @@ optimization, don't do & query per object in the set !
|
||||
$oObj->Set($sAttCode, $oTargetObj);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oObj->Set($sAttCode, $value);
|
||||
}
|
||||
|
||||
}
|
||||
$oSet->AddObject($oObj);
|
||||
}
|
||||
$aExtraParams = array();
|
||||
$aExtraParams['link_attr'] = $sExtKeyToMe;
|
||||
$aExtraParams['object_id'] = $iObjectId;
|
||||
$aExtraParams['target_attr'] = $sExtKeyToRemote;
|
||||
$aExtraParams['menu'] = false;
|
||||
$aExtraParams['select'] = false;
|
||||
|
||||
cmdbAbstractObject::DisplaySet($oPage, $oSet, $aExtraParams);
|
||||
}
|
||||
|
||||
|
||||
protected static function GetTargetClass($sClass, $sAttCode)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
switch(get_class($oAttDef))
|
||||
{
|
||||
case 'AttributeLinkedSetIndirect':
|
||||
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
|
||||
$sTargetClass = $oLinkingAttDef->GetTargetClass();
|
||||
break;
|
||||
|
||||
case 'AttributeLinkedSet':
|
||||
$sTargetClass = $sLinkedClass;
|
||||
break;
|
||||
}
|
||||
|
||||
return $sTargetClass;
|
||||
}
|
||||
|
||||
protected function GetObjectPickerDialog($oPage, $sTargetClass, $sOkFunction)
|
||||
{
|
||||
$sHTML = <<< EOF
|
||||
<div class="jqmWindow" id="ManageObjectsDlg_{$this->m_iInputId}">
|
||||
<div class="wizContainer">
|
||||
<div class="page_header"><h1 id="Manage_DlgTitle_{$this->m_iInputId}">Selected Objects</h1></div>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td>
|
||||
<p>Selected objects:</p>
|
||||
<button type="button" class="action" onClick="FilterLeft('$sTargetClass');"><span> Filter... </span></button>
|
||||
<p><select id="selected_objects_{$this->m_iInputId}" size="10" multiple onChange="Manage_UpdateButtons('$this->m_iInputId')" style="width:300px;">
|
||||
</select></p>
|
||||
</td>
|
||||
<td style="text-align:center; valign:middle;">
|
||||
<p><button type="button" id="btn_add_objects_{$this->m_iInputId}" onClick="Manage_AddObjects('$this->m_iInputId');"> << Add </button></p>
|
||||
<p><button type="button" id="btn_remove_objects_{$this->m_iInputId}" onClick="Manage_RemoveObjects('$this->m_iInputId');"> Remove >> </button></p>
|
||||
</td>
|
||||
<td>
|
||||
<p>Available objects:</p>
|
||||
<button type="button" class="action" onClick="FilterRight('$sTargetClass');"><span> Filter... </span></button>
|
||||
<p><select id="available_objects_{$this->m_iInputId}" size="10" multiple onChange="Manage_UpdateButtons('$this->m_iInputId')" style="width:300px;">
|
||||
</select></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<input type="submit" class="jqmClose" onClick="$('#ManageObjectsDlg_{$this->m_iInputId}').jqmHide(); $sOkFunction('$sTargetClass', 'selected_objects')" value=" Ok " /> <button type="button" class="jqmClose"> Cancel</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
EOF;
|
||||
$oPage->add_ready_script("$('#ManageObjectsDlg_$this->m_iInputId').jqm({overlay:70, modal:true, toTop:true});"); // jqModal Window
|
||||
//$oPage->add_ready_script("UpdateObjectList('$sClass');");
|
||||
return $sHTML;
|
||||
}
|
||||
|
||||
protected function GetLinkObjectDialog($oPage, $sId)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sAttCode);
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode($sLinkedClass);
|
||||
$sDefaultState = MetaModel::GetDefaultState($sLinkedClass);
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sAttCode);
|
||||
$sExtKeyToMe = $oAttDef->GetExtKeyToMe();
|
||||
$sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
|
||||
|
||||
$sHTML = "<div class=\"jqmWindow\" id=\"LinkDlg_$sId\">\n";
|
||||
$sHTML .= "<div class=\"wizContainer\">\n";
|
||||
$sHTML .= "<div class=\"page_header\"><h1>".MetaModel::GetName($sLinkedClass)." attributes</h1></div>\n";
|
||||
$sHTML .= "<form action=\"./UI.php\" onSubmit=\"return oLinkWidget$sId.OnLinkOk();\">\n";
|
||||
$index = 0;
|
||||
$aAttrsMap = array();
|
||||
$aDetails = array();
|
||||
foreach(MetaModel::ListAttributeDefs($sLinkedClass) as $sAttCode=>$oAttDef)
|
||||
{
|
||||
if ($sStateAttCode == $sAttCode)
|
||||
{
|
||||
// State attribute is always hidden from the UI
|
||||
//$sHTMLValue = $this->GetState();
|
||||
//$aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue);
|
||||
}
|
||||
else if (!$oAttDef->IsExternalField() && ($sAttCode != $sExtKeyToMe) && ($sAttCode != $sExtKeyToRemote))
|
||||
{
|
||||
$iFlags = MetaModel::GetAttributeFlags($sLinkedClass, $sDefaultState, $sAttCode);
|
||||
if ($iFlags & OPT_ATT_HIDDEN)
|
||||
{
|
||||
// Attribute is hidden, do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($iFlags & OPT_ATT_READONLY)
|
||||
{
|
||||
// Attribute is read-only
|
||||
$sHTMLValue = $this->GetAsHTML($sAttCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sValue = ""; //$this->Get($sAttCode);
|
||||
$sDisplayValue = ""; //$this->GetDisplayValue($sAttCode);
|
||||
$sSubId = $sId.'_'.$index;
|
||||
$aAttrsMap[$sAttCode] = $sSubId;
|
||||
$index++;
|
||||
$sHTMLValue = cmdbAbstractObject::GetFormElementForField($oPage, $sLinkedClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, $sSubId, $this->m_sAttCode);
|
||||
}
|
||||
$aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
$sHTML .= $oPage->GetDetails($aDetails);
|
||||
$sHTML .= "<input type=\"submit\" class=\"jqmClose\" onClick=\"oLinkWidget$sId.OnLinkOk()\" value=\" Ok \" /> <button type=\"button\" class=\"jqmClose\" onClick=\"oLinkWidget$sId.OnLinkCancel()\"> Cancel</button>\n";
|
||||
$sHTML .= "</form>\n";
|
||||
$sHTML .= "</div>\n";
|
||||
$sHTML .= "</div>\n";
|
||||
$oPage->add_ready_script("$('#LinkDlg_$sId').jqm({overlay:70, modal:true, toTop:true});"); // jqModal Window
|
||||
//$oPage->add_ready_script("UpdateObjectList('$sClass');");
|
||||
return $sHTML;
|
||||
}
|
||||
}
|
||||
?>
|
||||
397
application/uilinkswizard.class.inc.php
Normal file
397
application/uilinkswizard.class.inc.php
Normal file
@@ -0,0 +1,397 @@
|
||||
<?php
|
||||
class UILinksWizard
|
||||
{
|
||||
protected $m_sClass;
|
||||
protected $m_sLinkageAttr;
|
||||
protected $m_iObjectId;
|
||||
protected $m_sLinkedClass;
|
||||
protected $m_sLinkingAttCode;
|
||||
protected $m_aEditableFields;
|
||||
protected $m_aTableConfig;
|
||||
|
||||
public function __construct($sClass, $sLinkageAttr, $iObjectId, $sLinkedClass = '')
|
||||
{
|
||||
$this->m_sClass = $sClass;
|
||||
$this->m_sLinkageAttr = $sLinkageAttr;
|
||||
$this->m_iObjectId = $iObjectId;
|
||||
$this->m_sLinkedClass = $sLinkedClass; // Will try to guess below, if it's empty
|
||||
$this->m_sLinkingAttCode = ''; // Will be filled once we've found the attribute corresponding to the linked class
|
||||
|
||||
$this->m_aEditableFields = array();
|
||||
$this->m_aTableConfig = array();
|
||||
$this->m_aTableConfig['form::checkbox'] = array( 'label' => "<input class=\"select_all\" type=\"checkbox\" value=\"1\" onChange=\"var value = this.checked; $('.selection').each( function() { this.checked = value; } );OnSelectChange();\">", 'description' => "Select / Deselect All");
|
||||
foreach(MetaModel::GetAttributesList($this->m_sClass) as $sAttCode)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||
if ($oAttDef->IsExternalKey() && ($sAttCode != $this->m_sLinkageAttr))
|
||||
{
|
||||
if (empty($this->m_sLinkedClass))
|
||||
{
|
||||
// This is a class of objects we can manage !
|
||||
// Since nothing was specify, any class will do !
|
||||
$this->m_sLinkedClass = $oAttDef->GetTargetClass();
|
||||
$this->m_sLinkingAttCode = $sAttCode;
|
||||
}
|
||||
else if ($this->m_sLinkedClass == $oAttDef->GetTargetClass())
|
||||
{
|
||||
// This is the class of objects we want to manage !
|
||||
$this->m_sLinkingAttCode = $sAttCode;
|
||||
}
|
||||
}
|
||||
else if ( (!$oAttDef->IsExternalKey()) && (!$oAttDef->IsExternalField()))
|
||||
{
|
||||
$this->m_aEditableFields[] = $sAttCode;
|
||||
$this->m_aTableConfig[$sAttCode] = array( 'label' => $oAttDef->GetLabel(), 'description' => $oAttDef->GetDescription());
|
||||
}
|
||||
}
|
||||
if (empty($this->m_sLinkedClass))
|
||||
{
|
||||
throw( new Exception("Incorrect link definition: the class of objects to manage: '$sLinkedClass' was not found as an external key in the class '$sClass'"));
|
||||
}
|
||||
foreach(MetaModel::GetZListItems($this->m_sLinkedClass, 'list') as $sFieldCode)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
|
||||
$this->m_aTableConfig['static::'.$sFieldCode] = array( 'label' => $oAttDef->GetLabel(), 'description' => $oAttDef->GetDescription());
|
||||
}
|
||||
}
|
||||
|
||||
public function Display(WebPage $oP, UserContext $oContext, $aExtraParams = array())
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sLinkageAttr);
|
||||
$sTargetClass = $oAttDef->GetTargetClass();
|
||||
$oTargetObj = $oContext->GetObject($sTargetClass, $this->m_iObjectId);
|
||||
|
||||
$oP->set_title("iTop - ".MetaModel::GetName($this->m_sLinkedClass)." objects linked with ".MetaModel::GetName(get_class($oTargetObj)).": ".$oTargetObj->GetName());
|
||||
$oP->add("<div class=\"wizContainer\">\n");
|
||||
$oP->add("<form method=\"post\">\n");
|
||||
$oP->add("<div class=\"page_header\">\n");
|
||||
$oP->add("<input type=\"hidden\" id=\"linksToRemove\" name=\"linksToRemove\" value=\"\">\n");
|
||||
$oP->add("<input type=\"hidden\" name=\"operation\" value=\"do_modify_links\">\n");
|
||||
$oP->add("<input type=\"hidden\" name=\"class\" value=\"{$this->m_sClass}\">\n");
|
||||
$oP->add("<input type=\"hidden\" name=\"linkage\" value=\"{$this->m_sLinkageAttr}\">\n");
|
||||
$oP->add("<input type=\"hidden\" name=\"object_id\" value=\"{$this->m_iObjectId}\">\n");
|
||||
$oP->add("<input type=\"hidden\" name=\"linking_attcode\" value=\"{$this->m_sLinkingAttCode}\">\n");
|
||||
$oP->add("<h1>Manage ".MetaModel::GetName($this->m_sLinkedClass)."s linked with ".MetaModel::GetName(get_class($oTargetObj)).": <span class=\"hilite\">".$oTargetObj->GetHyperlink()."</span></h1>\n");
|
||||
$oP->add("</div>\n");
|
||||
$oP->add("<script type=\"text/javascript\">\n");
|
||||
$oP->add("function OnSelectChange()
|
||||
{
|
||||
var nbChecked = $('.selection:checked').length;
|
||||
if (nbChecked > 0)
|
||||
{
|
||||
$('#btnRemove').attr('disabled','');
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#btnRemove').attr('disabled','disabled');
|
||||
}
|
||||
}
|
||||
|
||||
function RemoveSelected()
|
||||
{
|
||||
$('.selection:checked').each(
|
||||
function()
|
||||
{
|
||||
$('#linksToRemove').val($('#linksToRemove').val() + ' ' + this.value);
|
||||
$('#row_'+this.value).remove();
|
||||
}
|
||||
);
|
||||
// Disable the button since all the selected items have been removed
|
||||
$('#btnRemove').attr('disabled','disabled');
|
||||
// Re-run the zebra plugin to properly highlight the remaining lines
|
||||
$('.listResults').trigger('update');
|
||||
|
||||
}
|
||||
|
||||
function AddObjects()
|
||||
{
|
||||
// TO DO: compute the list of objects already linked with the current Object
|
||||
$.get( 'ajax.render.php', { 'operation': 'addObjects',
|
||||
'class': '{$this->m_sClass}',
|
||||
'linkageAttr': '{$this->m_sLinkageAttr}',
|
||||
'linkedClass': '{$this->m_sLinkedClass}',
|
||||
'objectId': '{$this->m_iObjectId}'
|
||||
},
|
||||
function(data)
|
||||
{
|
||||
$('#ModalDlg').html(data);
|
||||
dlgWidth = $(document).width() - 100;
|
||||
$('#ModalDlg').css('width', dlgWidth);
|
||||
$('#ModalDlg').css('left', 50);
|
||||
$('#ModalDlg').css('top', 50);
|
||||
$('#ModalDlg').jqmShow();
|
||||
},
|
||||
'html'
|
||||
);
|
||||
}
|
||||
|
||||
function SearchObjectsToAdd(currentFormId)
|
||||
{
|
||||
var theMap = { 'class': '{$this->m_sClass}',
|
||||
'linkageAttr': '{$this->m_sLinkageAttr}',
|
||||
'linkedClass': '{$this->m_sLinkedClass}',
|
||||
'objectId': '{$this->m_iObjectId}'
|
||||
}
|
||||
|
||||
// Gather the parameters from the search form
|
||||
$('#'+currentFormId+' :input').each(
|
||||
function(i)
|
||||
{
|
||||
if (this.name != '')
|
||||
{
|
||||
theMap[this.name] = this.value;
|
||||
}
|
||||
}
|
||||
);
|
||||
theMap['operation'] = 'searchObjectsToAdd';
|
||||
|
||||
// Run the query and display the results
|
||||
$.get( 'ajax.render.php', theMap,
|
||||
function(data)
|
||||
{
|
||||
$('#SearchResultsToAdd').html(data);
|
||||
nb_rows = $('#SearchResultsToAdd table.listResults tr').length;
|
||||
if(nb_rows > 10)
|
||||
{
|
||||
yOffset = $('#ModalDlg').height() - $('#SearchResultsToAdd table.listResults tbody').height();
|
||||
tbodyHeight = $(document).height() - 100 - yOffset;
|
||||
if ($('#ModalDlg').height() > ($(document).height() - 100))
|
||||
{
|
||||
$('#SearchResultsToAdd table.listResults tbody').attr('height', tbodyHeight);
|
||||
$('#SearchResultsToAdd .listResults tbody').css('overflow', 'auto');
|
||||
$('#SearchResultsToAdd .listResults').tablesorter( { headers: { 0:{sorter: false }}, widgets: ['zebra']} ); // sortable and zebra tables
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
'html'
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function DoAddObjects(currentFormId)
|
||||
{
|
||||
var theMap = { 'class': '{$this->m_sClass}',
|
||||
'linkageAttr': '{$this->m_sLinkageAttr}',
|
||||
'linkedClass': '{$this->m_sLinkedClass}',
|
||||
'objectId': '{$this->m_iObjectId}'
|
||||
}
|
||||
|
||||
// Gather the parameters from the search form
|
||||
$('#'+currentFormId+' :input').each(
|
||||
function(i)
|
||||
{
|
||||
if ( (this.name != '') && ((this.type != 'checkbox') || (this.checked)) )
|
||||
{
|
||||
//console.log(this.type);
|
||||
arrayExpr = /\[\]$/;
|
||||
if (arrayExpr.test(this.name))
|
||||
{
|
||||
// Array
|
||||
if (theMap[this.name] == undefined)
|
||||
{
|
||||
theMap[this.name] = new Array();
|
||||
}
|
||||
theMap[this.name].push(this.value);
|
||||
}
|
||||
else
|
||||
{
|
||||
theMap[this.name] = this.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
theMap['operation'] = 'doAddObjects';
|
||||
|
||||
// Run the query and display the results
|
||||
$.get( 'ajax.render.php', theMap,
|
||||
function(data)
|
||||
{
|
||||
//console.log('Data: ' + data);
|
||||
if (data != '')
|
||||
{
|
||||
$('#empty_row').remove();
|
||||
}
|
||||
$('.listResults tbody').append(data);
|
||||
$('.listResults').trigger('update');
|
||||
$('.listResults').tablesorter( { headers: { 0:{sorter: false }}, widgets: ['zebra']} ); // sortable and zebra tables
|
||||
},
|
||||
'html'
|
||||
);
|
||||
$('#ModalDlg').jqmHide();
|
||||
return false;
|
||||
}
|
||||
|
||||
function InitForm()
|
||||
{
|
||||
// make sure that the form is clean
|
||||
$('.selection').each( function() { this.checked = false; });
|
||||
$('#btnRemove').attr('disabled','disabled');
|
||||
$('#linksToRemove').val('');
|
||||
}
|
||||
");
|
||||
$oP->Add("</script>\n");
|
||||
$oP->add_ready_script("InitForm();");
|
||||
$oFilter = $oContext->NewFilter($this->m_sClass);
|
||||
$oFilter->AddCondition($this->m_sLinkageAttr, $this->m_iObjectId, '=');
|
||||
$oSet = new DBObjectSet($oFilter);
|
||||
$aForm = array();
|
||||
while($oCurrentLink = $oSet->Fetch())
|
||||
{
|
||||
$aRow = array();
|
||||
$key = $oCurrentLink->GetKey();
|
||||
$oLinkedObj = $oContext->GetObject($this->m_sLinkedClass, $oCurrentLink->Get($this->m_sLinkingAttCode));
|
||||
|
||||
$aForm[$key] = $this->GetFormRow($oP, $oLinkedObj, $oCurrentLink);
|
||||
}
|
||||
//var_dump($aTableLabels);
|
||||
//var_dump($aForm);
|
||||
$this->DisplayFormTable($oP, $this->m_aTableConfig, $aForm);
|
||||
$oP->add("<span style=\"float:left;\"> <img src=\"../images/tv-item-last.gif\"> <input id=\"btnRemove\" type=\"button\" value=\" Remove ".MetaModel::GetName($this->m_sLinkedClass)."s \" onClick=\"RemoveSelected();\" >");
|
||||
$oP->add(" <input id=\"btnAdd\" type=\"button\" value=\" Add ".MetaModel::GetName($this->m_sLinkedClass)."s... \" onClick=\"AddObjects();\"></span>\n");
|
||||
$oP->add("<span style=\"float:right;\"><input id=\"btnCancel\" type=\"button\" value=\" Cancel \" onClick=\"goBack();\">");
|
||||
$oP->add(" <input id=\"btnOk\" type=\"submit\" value=\" Ok \"></span>\n");
|
||||
$oP->add("<span style=\"clear:both;\"><p> </p></span>\n");
|
||||
$oP->add("</div>\n");
|
||||
$oP->add("</form>\n");
|
||||
if (isset($aExtraParams['StartWithAdd']) && ($aExtraParams['StartWithAdd']))
|
||||
{
|
||||
$oP->add_ready_script("AddObjects();");
|
||||
}
|
||||
}
|
||||
|
||||
protected function GetFormRow($oP, $oLinkedObj, $currentLink = null )
|
||||
{
|
||||
$aRow = array();
|
||||
if(is_object($currentLink))
|
||||
{
|
||||
$key = $currentLink->GetKey();
|
||||
$sNameSuffix = "[$key]"; // To make a tabular form
|
||||
$aRow['form::checkbox'] = "<input class=\"selection\" type=\"checkbox\" onChange=\"OnSelectChange();\" value=\"$key\">";
|
||||
$aRow['form::checkbox'] .= "<input type=\"hidden\" name=\"linkId[$key]\" value=\"$key\">";
|
||||
foreach($this->m_aEditableFields as $sFieldCode)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sFieldCode);
|
||||
$aRow[$sFieldCode] = cmdbAbstractObject::GetFormElementForField($oP, $this->m_sClass, $sFieldCode, $oAttDef, $currentLink->Get($sFieldCode), '' /* DisplayValue */, $key, $sNameSuffix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// form for creating a new record
|
||||
$sNameSuffix = "[$currentLink]"; // To make a tabular form
|
||||
$aRow['form::checkbox'] = "<input class=\"selection\" type=\"checkbox\" onChange=\"OnSelectChange();\" value=\"$currentLink\">";
|
||||
$aRow['form::checkbox'] .= "<input type=\"hidden\" name=\"linkId[$currentLink]\" value=\"$currentLink\">";
|
||||
foreach($this->m_aEditableFields as $sFieldCode)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sFieldCode);
|
||||
$aRow[$sFieldCode] = cmdbAbstractObject::GetFormElementForField($oP, $this->m_sClass, $sFieldCode, $oAttDef, '' /* TO DO/ call GetDefaultValue */, '' /* DisplayValue */, '' /* id */, $sNameSuffix);
|
||||
}
|
||||
}
|
||||
foreach(MetaModel::GetZListItems($this->m_sLinkedClass, 'list') as $sFieldCode)
|
||||
{
|
||||
$aRow['static::'.$sFieldCode] = $oLinkedObj->GetAsHTML($sFieldCode);
|
||||
}
|
||||
return $aRow;
|
||||
}
|
||||
|
||||
protected function DisplayFormTable(WebPage $oP, $aConfig, $aData)
|
||||
{
|
||||
$oP->add("<table class=\"listResults\">\n");
|
||||
// Header
|
||||
$oP->add("<thead>\n");
|
||||
$oP->add("<tr>\n");
|
||||
foreach($aConfig as $sName=>$aDef)
|
||||
{
|
||||
$oP->add("<th title=\"".$aDef['description']."\">".$aDef['label']."</th>\n");
|
||||
}
|
||||
$oP->add("</tr>\n");
|
||||
$oP->add("</thead>\n");
|
||||
|
||||
// Content
|
||||
$oP->add("</tbody>\n");
|
||||
if (count($aData) == 0)
|
||||
{
|
||||
$oP->add("<tr id=\"empty_row\"><td colspan=\"".count($aConfig)."\" style=\"text-align:center;\">The list is empty, use 'Add...' to add elements.</td></td>");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($aData as $iRowId => $aRow)
|
||||
{
|
||||
$this->DisplayFormRow($oP, $aConfig, $aRow, $iRowId);
|
||||
}
|
||||
}
|
||||
$oP->add("</tbody>\n");
|
||||
|
||||
// Footer
|
||||
$oP->add("</table>\n");
|
||||
}
|
||||
|
||||
protected function DisplayFormRow(WebPage $oP, $aConfig, $aRow, $iRowId)
|
||||
{
|
||||
$oP->add("<tr id=\"row_$iRowId\">\n");
|
||||
foreach($aConfig as $sName=>$void)
|
||||
{
|
||||
$oP->add("<td>".$aRow[$sName]."</td>\n");
|
||||
}
|
||||
$oP->add("</tr>\n");
|
||||
}
|
||||
|
||||
public function DisplayAddForm(WebPage $oP, UserContext $oContext)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sLinkageAttr);
|
||||
$sTargetClass = $oAttDef->GetTargetClass();
|
||||
$oTargetObj = $oContext->GetObject($sTargetClass, $this->m_iObjectId);
|
||||
$oP->add("<div class=\"wizContainer\">\n");
|
||||
$oP->add("<div class=\"page_header\">\n");
|
||||
$oP->add("<h1>Add ".MetaModel::GetName($this->m_sLinkedClass)."s to ".MetaModel::GetName(get_class($oTargetObj)).": <span class=\"hilite\">".$oTargetObj->GetHyperlink()."</span></h1>\n");
|
||||
$oP->add("</div>\n");
|
||||
|
||||
$oFilter = $oContext->NewFilter($this->m_sLinkedClass);
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||
$oBlock->Display($oP, 'SearchFormToAdd', array('open' => true));
|
||||
$oP->Add("<form id=\"ObjectsAddForm\" OnSubmit=\"return DoAddObjects(this.id);\">\n");
|
||||
$oP->Add("<div id=\"SearchResultsToAdd\">\n");
|
||||
$oP->Add("<div style=\"height: 100px; background: #fff;border-color:#F6F6F1 #E6E6E1 #E6E6E1 #F6F6F1; border-style:solid; border-width:3px; text-align: center; vertical-align: center;\"><p>Use the search form above to search for objects to be added.</p></div>\n");
|
||||
$oP->Add("</div>\n");
|
||||
$oP->add("<input type=\"button\" value=\"Cancel\" onClick=\"$('#ModalDlg').jqmHide();\"> <input type=\"submit\" value=\" Add \">");
|
||||
$oP->Add("</div>\n");
|
||||
$oP->Add("</form>\n");
|
||||
$oP->add_ready_script("$('div#SearchFormToAdd form').bind('submit', function() {var the_form = this; SearchObjectsToAdd(the_form.id); return false;});");
|
||||
}
|
||||
|
||||
public function SearchObjectsToAdd(WebPage $oP, UserContext $oContext)
|
||||
{
|
||||
//$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sLinkageAttr);
|
||||
|
||||
$oFilter = $oContext->NewFilter($this->m_sLinkedClass);
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
$oBlock->Display($oP, 'ResultsToAdd', array('menu' => false, 'selection_mode' => true, 'display_limit' => false)); // Don't display the 'Actions' menu on the results
|
||||
}
|
||||
|
||||
public function DoAddObjects(WebPage $oP, UserContext $oContext, $aLinkedObjectIds = array())
|
||||
{
|
||||
//$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sLinkageAttr);
|
||||
//$sTargetClass = $oAttDef->GetTargetClass();
|
||||
//$oP->Add("<!-- nb of objects to add: ".count($aLinkedObjectIds)." -->\n"); // Just to make sure it's not empty
|
||||
$aTable = array();
|
||||
foreach($aLinkedObjectIds as $iObjectId)
|
||||
{
|
||||
$oLinkedObj = $oContext->GetObject($this->m_sLinkedClass, $iObjectId);
|
||||
if (is_object($oLinkedObj))
|
||||
{
|
||||
$aRow = $this->GetFormRow($oP, $oLinkedObj, -$iObjectId ); // Not yet created link get negative Ids
|
||||
$this->DisplayFormRow($oP, $this->m_aTableConfig, $aRow, -$iObjectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "Object: $sTargetClass - Id: $iObjectId not found <br/>\n";
|
||||
}
|
||||
}
|
||||
//var_dump($aTable);
|
||||
//$oP->Add("<!-- end of added list -->\n"); // Just to make sure it's not empty
|
||||
}
|
||||
}
|
||||
?>
|
||||
292
application/uiwizard.class.inc.php
Normal file
292
application/uiwizard.class.inc.php
Normal file
@@ -0,0 +1,292 @@
|
||||
<?php
|
||||
class UIWizard
|
||||
{
|
||||
protected $m_oPage;
|
||||
protected $m_sClass;
|
||||
protected $m_sTargetState;
|
||||
protected $m_aWizardSteps;
|
||||
|
||||
public function __construct($oPage, $sClass, $sTargetState = '')
|
||||
{
|
||||
$this->m_oPage = $oPage;
|
||||
$this->m_sClass = $sClass;
|
||||
if (empty($sTargetState))
|
||||
{
|
||||
$sTargetState = MetaModel::GetDefaultState($sClass);
|
||||
}
|
||||
$this->m_sTargetState = $sTargetState;
|
||||
$this->m_aWizardSteps = $this->ComputeWizardStructure();
|
||||
}
|
||||
|
||||
public function GetObjectClass() { return $this->m_sClass; }
|
||||
public function GetTargetState() { return $this->m_sTargetState; }
|
||||
public function GetWizardStructure() { return $this->m_aWizardSteps; }
|
||||
|
||||
/**
|
||||
* Displays one step of the wizard
|
||||
*/
|
||||
public function DisplayWizardStep($aStep, $iStepIndex, &$iMaxInputId, &$aFieldsMap, $bFinishEnabled = false, $aArgs = array())
|
||||
{
|
||||
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=\"../pages/UI.php\">\n");
|
||||
}
|
||||
$this->m_oPage->add("<div class=\"wizContainer\" id=\"wizStep$iStepIndex\" style=\"display:none;\">\n");
|
||||
$this->m_oPage->add("<a name=\"step$iStepIndex\" />\n");
|
||||
$aStates = MetaModel::EnumStates($this->m_sClass);
|
||||
$aDetails = array();
|
||||
$sJSHandlerCode = ''; // Javascript code to be executed each time this step of the wizard is entered
|
||||
foreach($aStep as $sAttCode)
|
||||
{
|
||||
if ($sAttCode != 'finalclass') // Do not display the attribute that stores the actual class name
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||
$sAttLabel = $oAttDef->GetLabel();
|
||||
$iOptions = isset($aStates[$this->m_sTargetState]['attribute_list'][$sAttCode]) ? $aStates[$this->m_sTargetState]['attribute_list'][$sAttCode] : 0;
|
||||
|
||||
$aPrerequisites = $oAttDef->GetPrerequisiteAttributes();
|
||||
if ($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT))
|
||||
{
|
||||
$aFields[$sAttCode] = array();
|
||||
foreach($aPrerequisites as $sCode)
|
||||
{
|
||||
$aFields[$sAttCode][$sCode] = '';
|
||||
}
|
||||
}
|
||||
if (count($aPrerequisites) > 0)
|
||||
{
|
||||
$aOptions[] = 'Prerequisites: '.implode(', ', $aPrerequisites);
|
||||
}
|
||||
|
||||
$sFieldFlag = ($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE)) ? ' <span class="hilite">*</span>' : '';
|
||||
$oDefaultValuesSet = $oAttDef->GetDefaultValue(); // @@@ 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);
|
||||
$aFieldsMap[$iMaxInputId] = $sAttCode;
|
||||
$aDetails[] = array('label' => $oAttDef->GetLabel().$sFieldFlag, 'value' => "<div id=\"field_$iMaxInputId\">$sHTMLValue</div>");
|
||||
if ($oAttDef->GetValuesDef() != null)
|
||||
{
|
||||
$sJSHandlerCode .= "\toWizardHelper.RequestAllowedValues('$sAttCode');\n";
|
||||
}
|
||||
if ($oAttDef->GetDefaultValue() != null)
|
||||
{
|
||||
$sJSHandlerCode .= "\toWizardHelper.RequestDefaultValue('$sAttCode');\n";
|
||||
}
|
||||
if ($oAttDef->IsLinkSet())
|
||||
{
|
||||
$sJSHandlerCode .= "\toLinkWidgetatt_$iMaxInputId.Init();";
|
||||
}
|
||||
$iMaxInputId++;
|
||||
}
|
||||
}
|
||||
//$aDetails[] = array('label' => '', 'value' => '<input type="button" value="Next >>">');
|
||||
$this->m_oPage->details($aDetails);
|
||||
$sBackButtonDisabled = ($iStepIndex <= 1) ? 'disabled' : '';
|
||||
$sDisabled = $bFinishEnabled ? '' : 'disabled';
|
||||
$nbSteps = count($this->m_aWizardSteps['mandatory']) + count($this->m_aWizardSteps['optional']);
|
||||
$this->m_oPage->add("<div style=\"text-align:center\">
|
||||
<input type=\"button\" value=\"<< Back \" $sBackButtonDisabled onClick=\"GoToStep($iStepIndex, $iStepIndex - 1)\" />
|
||||
<input type=\"button\" value=\" Next >>\" onClick=\"GoToStep($iStepIndex, 1+$iStepIndex)\" />
|
||||
<input type=\"button\" value=\" Finish \" $sDisabled onClick=\"GoToStep($iStepIndex, 1+$nbSteps)\" />
|
||||
</div>\n");
|
||||
$this->m_oPage->add("
|
||||
<script type=\"text/javascript\">
|
||||
function OnEnterStep{$iStepIndex}()
|
||||
{
|
||||
oWizardHelper.ResetQuery();
|
||||
oWizardHelper.UpdateWizard();
|
||||
|
||||
$sJSHandlerCode
|
||||
|
||||
oWizardHelper.AjaxQueryServer();
|
||||
}
|
||||
</script>\n");
|
||||
$this->m_oPage->add("</div>\n\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the final step of the wizard: a confirmation screen
|
||||
*/
|
||||
public function DisplayFinalStep($iStepIndex, $aFieldsMap)
|
||||
{
|
||||
$oAppContext = new ApplicationContext();
|
||||
$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->P("Final step: confirmation");
|
||||
$this->m_oPage->add("<input type=\"hidden\" name=\"operation\" value=\"wizard_apply_new\" />\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("<script type=\"text/javascript\">\n");
|
||||
$this->m_oPage->add("function OnEnterStep$iStepIndex() {\n");
|
||||
foreach($aFieldsMap as $iInputId => $sAttCode)
|
||||
{
|
||||
$this->m_oPage->add("\toWizardHelper.UpdateCurrentValue('$sAttCode');\n");
|
||||
}
|
||||
$this->m_oPage->add("\toWizardHelper.Preview('object_preview');\n");
|
||||
$this->m_oPage->add("\t$('#wizard_json_obj').val(oWizardHelper.ToJSON());\n");
|
||||
$this->m_oPage->add("}\n");
|
||||
$this->m_oPage->add("</script>\n");
|
||||
$this->m_oPage->add("<div id=\"object_preview\">\n");
|
||||
$this->m_oPage->add("</div>\n");
|
||||
$this->m_oPage->add($oAppContext->GetForForm());
|
||||
$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("</form>\n");
|
||||
}
|
||||
/**
|
||||
* Compute the order of the fields & pages in the wizard
|
||||
* @param $oPage iTopWebPage The current page (used to display error messages)
|
||||
* @param $sClass string Name of the class
|
||||
* @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
|
||||
*/
|
||||
protected function ComputeWizardStructure()
|
||||
{
|
||||
$aWizardSteps = array( 'mandatory' => array(), 'optional' => array());
|
||||
$aFieldsDone = array(); // Store all the fields that are already covered by a previous step of the wizard
|
||||
|
||||
$aStates = MetaModel::EnumStates($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())
|
||||
{
|
||||
$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
|
||||
// particular target state
|
||||
$aFields = array();
|
||||
foreach($aStates[$this->m_sTargetState]['attribute_list'] as $sAttCode => $iOptions)
|
||||
{
|
||||
if (isset($aMandatoryAttributes[$sAttCode]))
|
||||
{
|
||||
$aMandatoryAttributes[$sAttCode] |= $iOptions;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aMandatoryAttributes[$sAttCode] = $iOptions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check all the fields that *must* be included in the wizard
|
||||
$aFields = array();
|
||||
foreach($aMandatoryAttributes as $sAttCode => $iOptions)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||
$sAttLabel = $oAttDef->GetLabel();
|
||||
|
||||
if ( ($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) )
|
||||
{
|
||||
$aPrerequisites = $oAttDef->GetPrerequisiteAttributes();
|
||||
$aFields[$sAttCode] = array();
|
||||
foreach($aPrerequisites as $sCode)
|
||||
{
|
||||
$aFields[$sAttCode][$sCode] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now use the dependencies between the fields to order them
|
||||
while(count($aFields) > 0)
|
||||
{
|
||||
$aCurrentStep = array();
|
||||
foreach($aFields as $sAttCode => $aDependencies)
|
||||
{
|
||||
// All fields with no remaining dependencies can be entered at this
|
||||
// step of the wizard
|
||||
if (count($aDependencies) == 0)
|
||||
{
|
||||
$aCurrentStep[] = $sAttCode;
|
||||
$aFieldsDone[$sAttCode] = '';
|
||||
unset($aFields[$sAttCode]);
|
||||
// Remove this field from the dependencies of the other fields
|
||||
foreach($aFields as $sUpdatedCode => $aDummy)
|
||||
{
|
||||
// remove the dependency
|
||||
unset($aFields[$sUpdatedCode][$sAttCode]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count($aCurrentStep) == 0)
|
||||
{
|
||||
// This step of the wizard would contain NO field !
|
||||
echo "<strong>Error:</strong> Circular reference in the dependencies between the fields.";
|
||||
print_r($aFields);
|
||||
break;
|
||||
}
|
||||
$aWizardSteps['mandatory'][] = $aCurrentStep;
|
||||
}
|
||||
|
||||
|
||||
// Now computes the steps to fill the optional fields
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode($this->m_sClass);
|
||||
$aFields = array(); // reset
|
||||
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;
|
||||
if ( ($sStateAttCode != $sAttCode) &&
|
||||
(!$oAttDef->IsExternalField()) &&
|
||||
(($iOptions & (OPT_ATT_HIDDEN | OPT_ATT_READONLY)) == 0) &&
|
||||
(!isset($aFieldsDone[$sAttCode])) )
|
||||
|
||||
{
|
||||
// 'State', external fields, read-only and hidden fields
|
||||
// and fields that are already listed in the wizard
|
||||
// are removed from the 'optional' part of the wizard
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
|
||||
$aPrerequisites = $oAttDef->GetPrerequisiteAttributes();
|
||||
$aFields[$sAttCode] = array();
|
||||
foreach($aPrerequisites as $sCode)
|
||||
{
|
||||
if (!isset($aFieldsDone[$sCode]))
|
||||
{
|
||||
// retain only the dependencies that were not covered
|
||||
// in the 'mandatory' part of the wizard
|
||||
$aFields[$sAttCode][$sCode] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Now use the dependencies between the fields to order them
|
||||
while(count($aFields) > 0)
|
||||
{
|
||||
$aCurrentStep = array();
|
||||
foreach($aFields as $sAttCode => $aDependencies)
|
||||
{
|
||||
// All fields with no remaining dependencies can be entered at this
|
||||
// step of the wizard
|
||||
if (count($aDependencies) == 0)
|
||||
{
|
||||
$aCurrentStep[] = $sAttCode;
|
||||
$aFieldsDone[$sAttCode] = '';
|
||||
unset($aFields[$sAttCode]);
|
||||
// Remove this field from the dependencies of the other fields
|
||||
foreach($aFields as $sUpdatedCode => $aDummy)
|
||||
{
|
||||
// remove the dependency
|
||||
unset($aFields[$sUpdatedCode][$sAttCode]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count($aCurrentStep) == 0)
|
||||
{
|
||||
// This step of the wizard would contain NO field !
|
||||
$oPage->add("<strong>Error:</strong> Circular reference in the dependencies between the fields.");
|
||||
print_r($aFields);
|
||||
break;
|
||||
}
|
||||
$aWizardSteps['optional'][] = $aCurrentStep;
|
||||
}
|
||||
return $aWizardSteps;
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
106
application/usercontext.class.inc.php
Normal file
106
application/usercontext.class.inc.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
require_once('../core/cmdbobject.class.inc.php');
|
||||
require_once('../core/userrights.class.inc.php');
|
||||
/**
|
||||
* Helper class to capture a user's restrictions (access rights, profiles...) as a set of limiting conditions
|
||||
*
|
||||
* **** NOW OBSOLETE *** SHOULD BE REPLACED EVERYWHERE BY UserRights *****
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Usage:
|
||||
* 1) Build the user's context (from her rights, a lookup in the database, a cookie, whatever)
|
||||
* $oContext = new UserContext();
|
||||
* $oContext->AddCondition('SomeClass', 'someFilter', 'SomeValue', '=');
|
||||
* ...
|
||||
*
|
||||
* 2) Use the restrictions contained in the context when retrieving objects either when:
|
||||
* getting directly an instance of an object
|
||||
* $oObj = $oContext->GetObject('myClass', 'someKey'); // Instead of $oObj = MetaModel::GetObject('Klass', 'someKey');
|
||||
* or when building a new search filter
|
||||
* $oFilter = $oContext->NewFilter('myClass'); // Instead of $oFilter = new CMDBSearchFilter('Klass');
|
||||
*/
|
||||
class UserContext
|
||||
{
|
||||
/**
|
||||
* Hash array to store the restricting conditions by myClass
|
||||
*/
|
||||
protected $m_aConditions;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->m_aConditions = array();
|
||||
}
|
||||
/**
|
||||
* Create a new search filter for the given class of objects that already contains the context's restrictions
|
||||
*/
|
||||
public function NewFilter($sClass)
|
||||
{
|
||||
return UserRights::GetFilter($sClass);
|
||||
/*
|
||||
$oFilter = new CMDBSearchFilter($sClass);
|
||||
foreach($this->m_aConditions as $sConditionClass => $aConditionList)
|
||||
{
|
||||
// Add to the filter all the conditions of the parent classes of this class
|
||||
if ($this->IsSubclass($sConditionClass,$sClass))
|
||||
{
|
||||
foreach($aConditionList as $sFilterCode => $aCondition)
|
||||
{
|
||||
$oFilter->AddCondition($sFilterCode, $aCondition['value'], $aCondition['operator']);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $oFilter;
|
||||
*/
|
||||
}
|
||||
/**
|
||||
* Retrieve an instance of an object (if allowed by the context)
|
||||
*/
|
||||
public function GetObject($sClass, $sKey)
|
||||
{
|
||||
$oObject = null;
|
||||
$oFilter = $this->NewFilter($sClass);
|
||||
$oFilter->AddCondition('pkey', $sKey, '=');
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
if ($oSet->Count() > 0)
|
||||
{
|
||||
$oObject = $oSet->Fetch();
|
||||
}
|
||||
return $oObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a restriction to the context for a given class of objects (and all its persistent subclasses)
|
||||
*/
|
||||
public function AddCondition($sClass, $sFilterCode, $value, $sOperator)
|
||||
{
|
||||
if(!isset($this->m_aConditions[$sClass]))
|
||||
{
|
||||
$this->m_aConditions[$sClass] = array();
|
||||
}
|
||||
$this->m_aConditions[$sClass][$sFilterCode] = array('value'=>$value, 'operator'=>$sOperator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given class is a subclass of (or same as) another one
|
||||
*/
|
||||
protected function IsSubclass($sParentClass, $sSubclass)
|
||||
{
|
||||
$bResult = false;
|
||||
if ($sParentClass == $sSubclass)
|
||||
{
|
||||
$bResult = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aParentList = MetaModel::EnumParentClasses($sSubclass);
|
||||
$bResult = in_array($sParentClass, $aParentList);
|
||||
}
|
||||
return $bResult;
|
||||
}
|
||||
}
|
||||
?>
|
||||
199
application/utils.inc.php
Normal file
199
application/utils.inc.php
Normal file
@@ -0,0 +1,199 @@
|
||||
<?php
|
||||
require_once('../core/config.class.inc.php');
|
||||
|
||||
define('ITOP_CONFIG_FILE', '../config-itop.php');
|
||||
|
||||
class FileUploadException extends Exception
|
||||
{
|
||||
}
|
||||
|
||||
class utils
|
||||
{
|
||||
private static $m_oConfig = null;
|
||||
|
||||
public static function ReadParam($sName, $defaultValue = "")
|
||||
{
|
||||
return isset($_REQUEST[$sName]) ? $_REQUEST[$sName] : $defaultValue;
|
||||
}
|
||||
|
||||
public static function ReadPostedParam($sName, $defaultValue = "")
|
||||
{
|
||||
return isset($_POST[$sName]) ? $_POST[$sName] : $defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an uploaded file and turns it into an ormDocument object - Triggers an exception in case of error
|
||||
* @param string $sName Name of the input used from uploading the file
|
||||
* @return ormDocument The uploaded file (can be 'empty' if nothing was uploaded)
|
||||
*/
|
||||
public static function ReadPostedDocument($sName)
|
||||
{
|
||||
$oDocument = new ormDocument(); // an empty document
|
||||
if(isset($_FILES[$sName]))
|
||||
{
|
||||
switch($_FILES[$sName]['error'])
|
||||
{
|
||||
case UPLOAD_ERR_OK:
|
||||
$doc_content = file_get_contents($_FILES[$sName]['tmp_name']);
|
||||
$sMimeType = $_FILES[$sName]['type'];
|
||||
if (function_exists('finfo_file'))
|
||||
{
|
||||
// as of PHP 5.3 the fileinfo extension is bundled within PHP
|
||||
// in which case we don't trust the mime type provided by the browser
|
||||
$rInfo = @finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
|
||||
if ($rInfo !== false)
|
||||
{
|
||||
$sType = @finfo_file($rInfo, $file);
|
||||
if ( ($sType !== false)
|
||||
&& is_string($sType)
|
||||
&& (strlen($sType)>0))
|
||||
{
|
||||
$sMimeType = $sType;
|
||||
}
|
||||
}
|
||||
@finfo_close($finfo);
|
||||
}
|
||||
$oDocument = new ormDocument($doc_content, $sMimeType, $_FILES[$sName]['name']);
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_NO_FILE:
|
||||
// no file to load, it's a normal case, just return an empty document
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_FORM_SIZE:
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
throw new FileUploadException("Uploaded file is too big. (Max allowed size is ".ini_get('upload_max_filesize').". Check you PHP configuration for upload_max_filesize.");
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_PARTIAL:
|
||||
throw new FileUploadException("File upload failed, file has been truncated.");
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_NO_TMP_DIR:
|
||||
throw new FileUploadException("Missing a temporary folder.");
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_CANT_WRITE:
|
||||
throw new FileUploadException("Unable to write the temporary file to the disk (upload_tmp_dir = ".ini_get('upload_tmp_dir').")");
|
||||
break;
|
||||
|
||||
case UPLOAD_ERR_EXTENSION:
|
||||
throw new FileUploadException("File upload stopped by extension. (Original file name: ".$_FILES[$sName]['name'].")");
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new FileUploadException("File upload failed, unknown cause (Error code = ".$_FILES[$sName]['error'].")");
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
return $oDocument;
|
||||
}
|
||||
|
||||
public static function GetNewTransactionId()
|
||||
{
|
||||
// TO DO implement the real mechanism here
|
||||
return sprintf("%08x", rand(0,2000000000));
|
||||
}
|
||||
|
||||
public static function IsTransactionValid($sId)
|
||||
{
|
||||
// TO DO implement the real mechanism here
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function ReadFromFile($sFileName)
|
||||
{
|
||||
if (!file_exists($sFileName)) return false;
|
||||
return file_get_contents($sFileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access to the application config file
|
||||
* @param none
|
||||
* @return Config The Config object initialized from the application config file
|
||||
*/
|
||||
public static function GetConfig()
|
||||
{
|
||||
if (self::$m_oConfig == null)
|
||||
{
|
||||
self::$m_oConfig = new Config(ITOP_CONFIG_FILE);
|
||||
}
|
||||
return self::$m_oConfig;
|
||||
}
|
||||
/**
|
||||
* Helper function to convert a value expressed in a 'user friendly format'
|
||||
* as in php.ini, e.g. 256k, 2M, 1G etc. Into a number of bytes
|
||||
* @param mixed $value The value as read from php.ini
|
||||
* @return number
|
||||
*/
|
||||
public static function ConvertToBytes( $value )
|
||||
{
|
||||
$iReturn = $value;
|
||||
if ( !is_numeric( $value ) )
|
||||
{
|
||||
$iLength = strlen( $value );
|
||||
$iReturn = substr( $value, 0, $iLength - 1 );
|
||||
$sUnit = strtoupper( substr( $value, $iLength - 1 ) );
|
||||
switch ( $sUnit )
|
||||
{
|
||||
case 'G':
|
||||
$iReturn *= 1024;
|
||||
case 'M':
|
||||
$iReturn *= 1024;
|
||||
case 'K':
|
||||
$iReturn *= 1024;
|
||||
}
|
||||
}
|
||||
return $iReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an absolute URL to the current page
|
||||
* @param $bQueryString bool True to also get the query string, false otherwise
|
||||
* @return string The absolute URL to the current page
|
||||
*/
|
||||
static public function GetAbsoluteUrl($bQueryString = true)
|
||||
{
|
||||
// Build an absolute URL to this page on this server/port
|
||||
$sServerName = $_SERVER['SERVER_NAME'];
|
||||
$sProtocol = isset($_SERVER['HTTPS']) ? 'https' : 'http';
|
||||
if ($sProtocol == 'http')
|
||||
{
|
||||
$sPort = ($_SERVER['SERVER_PORT'] == 80) ? '' : ':'.$_SERVER['SERVER_PORT'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$sPort = ($_SERVER['SERVER_PORT'] == 443) ? '' : ':'.$_SERVER['SERVER_PORT'];
|
||||
}
|
||||
// $_SERVER['REQUEST_URI'] is empty when running on IIS
|
||||
// Let's use Ivan Tcholakov's fix (found on www.dokeos.com)
|
||||
if (!empty($_SERVER['REQUEST_URI']))
|
||||
{
|
||||
$sPath = $_SERVER['REQUEST_URI'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$sPath = $_SERVER['SCRIPT_NAME'];
|
||||
if (!empty($_SERVER['QUERY_STRING']))
|
||||
{
|
||||
$sPath .= '?'.$_SERVER['QUERY_STRING'];
|
||||
}
|
||||
$_SERVER['REQUEST_URI'] = $sPath;
|
||||
}
|
||||
$sPath = $_SERVER['REQUEST_URI'];
|
||||
if (!$bQueryString)
|
||||
{
|
||||
// remove all the parameters from the query string
|
||||
$iQuestionMarkPos = strpos($sPath, '?');
|
||||
if ($iQuestionMarkPos !== false)
|
||||
{
|
||||
$sPath = substr($sPath, 0, $iQuestionMarkPos);
|
||||
}
|
||||
}
|
||||
$sUrl = "$sProtocol://{$sServerName}{$sPort}{$sPath}";
|
||||
|
||||
return $sUrl;
|
||||
}
|
||||
}
|
||||
?>
|
||||
333
application/webpage.class.inc.php
Normal file
333
application/webpage.class.inc.php
Normal file
@@ -0,0 +1,333 @@
|
||||
<?php
|
||||
/**
|
||||
* Simple helper class to ease the production of HTML pages
|
||||
*
|
||||
* This class provide methods to add content, scripts, includes... to a web page
|
||||
* and renders the full web page by putting the elements in the proper place & order
|
||||
* when the output() method is called.
|
||||
* Usage:
|
||||
* $oPage = new WebPage("Title of my page");
|
||||
* $oPage->p("Hello World !");
|
||||
* $oPage->output();
|
||||
*/
|
||||
class WebPage
|
||||
{
|
||||
protected $s_title;
|
||||
protected $s_content;
|
||||
protected $s_deferred_content;
|
||||
protected $a_scripts;
|
||||
protected $a_styles;
|
||||
protected $a_include_scripts;
|
||||
protected $a_include_stylesheets;
|
||||
protected $a_headers;
|
||||
protected $a_base;
|
||||
|
||||
public function __construct($s_title)
|
||||
{
|
||||
$this->s_title = $s_title;
|
||||
$this->s_content = "";
|
||||
$this->s_deferred_content = '';
|
||||
$this->a_scripts = array();
|
||||
$this->a_styles = array();
|
||||
$this->a_linked_scripts = array();
|
||||
$this->a_linked_stylesheets = array();
|
||||
$this->a_headers = array();
|
||||
$this->a_base = array( 'href' => '', 'target' => '');
|
||||
ob_start(); // Start capturing the output
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the title of the page after its creation
|
||||
*/
|
||||
public function set_title($s_title)
|
||||
{
|
||||
$this->s_title = $s_title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a default URL and a default target for all links on a page
|
||||
*/
|
||||
public function set_base($s_href = '', $s_target = '')
|
||||
{
|
||||
$this->a_base['href'] = $s_href;
|
||||
$this->a_base['target'] = $s_target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add any text or HTML fragment to the body of the page
|
||||
*/
|
||||
public function add($s_html)
|
||||
{
|
||||
$this->s_content .= $s_html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add any text or HTML fragment at the end of the body of the page
|
||||
* This is useful to add hidden content, DIVs or FORMs that should not
|
||||
* be embedded into each other.
|
||||
*/
|
||||
public function add_at_the_end($s_html)
|
||||
{
|
||||
$this->s_deferred_content .= $s_html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a paragraph to the body of the page
|
||||
*/
|
||||
public function p($s_html)
|
||||
{
|
||||
$this->add($this->GetP($s_html));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a paragraph to the body of the page
|
||||
*/
|
||||
public function GetP($s_html)
|
||||
{
|
||||
return "<p>$s_html</p>\n";
|
||||
}
|
||||
|
||||
public function table($aConfig, $aData, $aParams = array())
|
||||
{
|
||||
$this->add($this->GetTable($aConfig, $aData, $aParams));
|
||||
}
|
||||
|
||||
public function GetTable($aConfig, $aData, $aParams = array())
|
||||
{
|
||||
$oAppContext = new ApplicationContext();
|
||||
|
||||
static $iNbTables = 0;
|
||||
$iNbTables++;
|
||||
$sHtml = "";
|
||||
$sHtml .= "<table class=\"listResults\">\n";
|
||||
$sHtml .= "<thead>\n";
|
||||
$sHtml .= "<tr>\n";
|
||||
foreach($aConfig as $sName=>$aDef)
|
||||
{
|
||||
$sHtml .= "<th title=\"".$aDef['description']."\">".$aDef['label']."</th>\n";
|
||||
}
|
||||
$sHtml .= "</tr>\n";
|
||||
$sHtml .= "</thead>\n";
|
||||
$sHtml .= "<tbody>\n";
|
||||
foreach($aData as $aRow)
|
||||
{
|
||||
if (false) //(isset($aParams['preview']) && $aParams['preview'])
|
||||
{
|
||||
$sHtml .= "<tr id=\"Row_".$iNbTables."_".$aRow['key']."\" onClick=\"DisplayPreview(".$iNbTables.",".$aRow['key'].",'".$aParams['class']."')\">\n";
|
||||
}
|
||||
else if (isset($aRow['key']))
|
||||
{
|
||||
$sHtml .= "<tr onDblClick=\"DisplayDetails(".$aRow['key'].",'".$aParams['class']."')\">\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml .= "<tr>\n";
|
||||
}
|
||||
foreach($aConfig as $sName=>$aAttribs)
|
||||
{
|
||||
$sClass = isset($aAttribs['class']) ? 'class="'.$aAttribs['class'].'"' : '';
|
||||
if ($sName != 'key')
|
||||
{
|
||||
$sValue = ($aRow[$sName] === '') ? ' ' : $aRow[$sName];
|
||||
$sHtml .= "<td $sClass>$sValue</td>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sUIPage = cmdbAbstractObject::ComputeUIPage($aParams['class']);
|
||||
$sHtml .= "<td><a class=\"no-arrow\" href=\"$sUIPage?operation=details&id=".$aRow['key']."&class=".$aParams['class']."&".$oAppContext->GetForLink()."\"><img src=\"../images/zoom.gif\" title=\"Details\" border=\"0\"></a></td>\n";
|
||||
}
|
||||
}
|
||||
$sHtml .= "</tr>\n";
|
||||
}
|
||||
$sHtml .= "</tbody>\n";
|
||||
$sHtml .= "</table>\n";
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add some Javascript to the header of the page
|
||||
*/
|
||||
public function add_script($s_script)
|
||||
{
|
||||
$this->a_scripts[] = $s_script;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add some Javascript to the header of the page
|
||||
*/
|
||||
public function add_ready_script($s_script)
|
||||
{
|
||||
// Do nothing silently... this is not supported by this type of page...
|
||||
}
|
||||
/**
|
||||
* Add some CSS definitions to the header of the page
|
||||
*/
|
||||
public function add_style($s_style)
|
||||
{
|
||||
$this->a_styles[] = $s_style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a script (as an include, i.e. link) to the header of the page
|
||||
*/
|
||||
public function add_linked_script($s_linked_script)
|
||||
{
|
||||
$this->a_linked_scripts[] = $s_linked_script;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a CSS stylesheet (as an include, i.e. link) to the header of the page
|
||||
*/
|
||||
public function add_linked_stylesheet($s_linked_stylesheet, $s_condition = "")
|
||||
{
|
||||
$this->a_linked_stylesheets[] = array( 'link' => $s_linked_stylesheet, 'condition' => $s_condition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add some custom header to the page
|
||||
*/
|
||||
public function add_header($s_header)
|
||||
{
|
||||
$this->a_headers[] = $s_header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add needed headers to the page so that it will no be cached
|
||||
*/
|
||||
public function no_cache()
|
||||
{
|
||||
$this->add_header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
|
||||
$this->add_header("Expires: Fri, 17 Jul 1970 05:00:00 GMT"); // Date in the past
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a special kind of TABLE useful for displaying the details of an object from a hash array of data
|
||||
*/
|
||||
public function details($aFields)
|
||||
{
|
||||
|
||||
$this->add($this->GetDetails($aFields));
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a special kind of TABLE useful for displaying the details of an object from a hash array of data
|
||||
*/
|
||||
public function GetDetails($aFields)
|
||||
{
|
||||
$sHtml = "<table>\n";
|
||||
$sHtml .= "<tbody>\n";
|
||||
foreach($aFields as $aAttrib)
|
||||
{
|
||||
$sHtml .= "<tr>\n";
|
||||
// By Rom, for csv import, proposed to show several values for column selection
|
||||
if (is_array($aAttrib['value']))
|
||||
{
|
||||
$sHtml .= "<td class=\"label\">".$aAttrib['label']."</td><td>".implode("</td><td>", $aAttrib['value'])."</td>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml .= "<td class=\"label\">".$aAttrib['label']."</td><td>".$aAttrib['value']."</td>\n";
|
||||
}
|
||||
$sHtml .= "</tr>\n";
|
||||
}
|
||||
$sHtml .= "</tbody>\n";
|
||||
$sHtml .= "</table>\n";
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs (via some echo) the complete HTML page by assembling all its elements
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
foreach($this->a_headers as $s_header)
|
||||
{
|
||||
header($s_header);
|
||||
}
|
||||
$s_captured_output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
|
||||
echo "<html>\n";
|
||||
echo "<head>\n";
|
||||
echo "<title>{$this->s_title}</title>\n";
|
||||
echo $this->get_base_tag();
|
||||
foreach($this->a_linked_scripts as $s_script)
|
||||
{
|
||||
echo "<script type=\"text/javascript\" src=\"$s_script\"></script>\n";
|
||||
}
|
||||
if (count($this->a_scripts)>0)
|
||||
{
|
||||
echo "<script type=\"text/javascript\">\n";
|
||||
foreach($this->a_scripts as $s_script)
|
||||
{
|
||||
echo "$s_script\n";
|
||||
}
|
||||
echo "</script>\n";
|
||||
}
|
||||
foreach($this->a_linked_stylesheets as $a_stylesheet)
|
||||
{
|
||||
if ($a_stylesheet['condition'] != "")
|
||||
{
|
||||
echo "<!--[if {$a_stylesheet['condition']}]>\n";
|
||||
}
|
||||
echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"{$a_stylesheet['link']}\" />\n";
|
||||
if ($a_stylesheet['condition'] != "")
|
||||
{
|
||||
echo "<![endif]-->\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (count($this->a_styles)>0)
|
||||
{
|
||||
echo "<style>\n";
|
||||
foreach($this->a_styles as $s_style)
|
||||
{
|
||||
echo "$s_style\n";
|
||||
}
|
||||
echo "</style>\n";
|
||||
}
|
||||
echo "</head>\n";
|
||||
echo "<body>\n";
|
||||
echo $this->s_content;
|
||||
if (trim($s_captured_output) != "")
|
||||
{
|
||||
echo "<div class=\"raw_output\">$s_captured_output</div>\n";
|
||||
}
|
||||
echo $this->s_deferred_content;
|
||||
echo "</body>\n";
|
||||
echo "</html>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a series of hidden field[s] from an array
|
||||
*/
|
||||
// By Rom - je verrais bien une serie d'outils pour gerer des parametres que l'on retransmet entre pages d'un wizard...
|
||||
// ptet deriver webpage en webwizard
|
||||
public function add_input_hidden($sLabel, $aData)
|
||||
{
|
||||
foreach($aData as $sKey=>$sValue)
|
||||
{
|
||||
$this->add("<input type=\"hidden\" name=\"".$sLabel."[$sKey]\" value=\"$sValue\">");
|
||||
}
|
||||
}
|
||||
|
||||
protected function get_base_tag()
|
||||
{
|
||||
$sTag = '';
|
||||
if (($this->a_base['href'] != '') || ($this->a_base['target'] != ''))
|
||||
{
|
||||
$sTag = '<base ';
|
||||
if (($this->a_base['href'] != ''))
|
||||
{
|
||||
$sTag .= "href =\"{$this->a_base['href']}\" ";
|
||||
}
|
||||
if (($this->a_base['target'] != ''))
|
||||
{
|
||||
$sTag .= "target =\"{$this->a_base['target']}\" ";
|
||||
}
|
||||
$sTag .= " />\n";
|
||||
}
|
||||
return $sTag;
|
||||
}
|
||||
}
|
||||
?>
|
||||
232
application/wizardhelper.class.inc.php
Normal file
232
application/wizardhelper.class.inc.php
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
require_once('../application/uiwizard.class.inc.php');
|
||||
|
||||
class WizardHelper
|
||||
{
|
||||
protected $m_aData;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
/**
|
||||
* Constructs the PHP target object from the parameters sent to the web page by the wizard
|
||||
* @param boolean $bReadUploadedFiles True to also ready any uploaded file (for blob/document fields)
|
||||
* @return object
|
||||
*/
|
||||
public function GetTargetObject($bReadUploadedFiles = false)
|
||||
{
|
||||
$oObj = MetaModel::NewObject($this->m_aData['m_sClass']);
|
||||
foreach($this->m_aData['m_aCurrentValues'] as $iIndex => $value)
|
||||
{
|
||||
$sAttCode = array_search($iIndex, $this->m_aData['m_oFieldsMap']);
|
||||
// Because this is stored in a Javascript array, unused indexes
|
||||
// are filled with null values
|
||||
if ( ($sAttCode !== false) && ($value !== null))
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_aData['m_sClass'], $sAttCode);
|
||||
if (($oAttDef->IsLinkSet()) && ($value != '') )
|
||||
{
|
||||
// special handling for lists
|
||||
// assumes this is handled as an array of objects
|
||||
// thus encoded in json like: [ { name:'link1', 'id': 123}, { name:'link2', 'id': 124}...]
|
||||
$aData = json_decode($value, true); // true means decode as a hash array (not an object)
|
||||
// Check what are the meaningful attributes
|
||||
$aFields = $this->GetLinkedWizardStructure($oAttDef);
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
$aLinkedObjectsArray = array();
|
||||
if (!is_array($aData))
|
||||
{
|
||||
echo ("aData: '$aData' (value: '$value')\n");
|
||||
}
|
||||
foreach($aData as $aLinkedObject)
|
||||
{
|
||||
$oLinkedObj = MetaModel::NewObject($sLinkedClass);
|
||||
foreach($aFields as $sLinkedAttCode)
|
||||
{
|
||||
if ( isset($aLinkedObject[$sLinkedAttCode]) && ($aLinkedObject[$sLinkedAttCode] !== null) )
|
||||
{
|
||||
$sLinkedAttDef = MetaModel::GetAttributeDef($sLinkedClass, $sLinkedAttCode);
|
||||
if (($sLinkedAttDef->IsExternalKey()) && ($aLinkedObject[$sLinkedAttCode] != '') )
|
||||
{
|
||||
// For external keys: load the target object so that external fields
|
||||
// get filled too
|
||||
$oTargetObj = MetaModel::GetObject($sLinkedAttDef->GetTargetClass(), $aLinkedObject[$sLinkedAttCode]);
|
||||
$oLinkedObj->Set($sLinkedAttCode, $oTargetObj);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oLinkedObj->Set($sLinkedAttCode, $aLinkedObject[$sLinkedAttCode]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$aLinkedObjectsArray[] = $oLinkedObj;
|
||||
}
|
||||
$oSet = DBObjectSet::FromArray($sLinkedClass, $aLinkedObjectsArray);
|
||||
$oObj->Set($sAttCode, $oSet);
|
||||
}
|
||||
else if ( $oAttDef->GetEditClass() == 'Document' )
|
||||
{
|
||||
if ($bReadUploadedFiles)
|
||||
{
|
||||
$oDocument = utils::ReadPostedDocument('file_'.$sAttCode);
|
||||
$oObj->Set($sAttCode, $oDocument);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a new empty document, just for displaying the file name
|
||||
$oDocument = new ormDocument(null, '', $value);
|
||||
$oObj->Set($sAttCode, $oDocument);
|
||||
}
|
||||
}
|
||||
else if (($oAttDef->IsExternalKey()) && (!empty($value)) )
|
||||
{
|
||||
// For external keys: load the target object so that external fields
|
||||
// get filled too
|
||||
$oTargetObj = MetaModel::GetObject($oAttDef->GetTargetClass(), $value);
|
||||
$oObj->Set($sAttCode, $oTargetObj);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oObj->Set($sAttCode, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $oObj;
|
||||
}
|
||||
|
||||
public function GetFieldsForDefaultValue()
|
||||
{
|
||||
return $this->m_aData['m_aDefaultValueRequested'];
|
||||
}
|
||||
|
||||
public function SetDefaultValue($sAttCode, $value)
|
||||
{
|
||||
// Protect against a request for a non existing field
|
||||
if (isset($this->m_aData['m_oFieldsMap'][$sAttCode]))
|
||||
{
|
||||
$iIndex = $this->m_aData['m_oFieldsMap'][$sAttCode];
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_aData['m_sClass'], $sAttCode);
|
||||
if ($oAttDef->GetEditClass() == 'List')
|
||||
{
|
||||
// special handling for lists
|
||||
// this as to be handled as an array of objects
|
||||
// thus encoded in json like: [ { name:'link1', 'id': 123}, { name:'link2', 'id': 124}...]
|
||||
// NOT YET IMPLEMENTED !!
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
$oSet = $value;
|
||||
$aData = array();
|
||||
$aFields = $this->GetLinkedWizardStructure($oAttDef);
|
||||
while($oSet->fetch())
|
||||
{
|
||||
foreach($aFields as $sLinkedAttCode)
|
||||
{
|
||||
$aRow[$sAttCode] = $oLinkedObj->Get($sLinkedAttCode);
|
||||
}
|
||||
$aData[] = $aRow;
|
||||
}
|
||||
$this->m_aData['m_aDefaultValue'][$iIndex] = json_encode($aData);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal handling for all other scalar attributes
|
||||
$this->m_aData['m_aDefaultValue'][$iIndex] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function GetFieldsForAllowedValues()
|
||||
{
|
||||
return $this->m_aData['m_aAllowedValuesRequested'];
|
||||
}
|
||||
|
||||
public function SetAllowedValuesHtml($sAttCode, $sHtml)
|
||||
{
|
||||
// Protect against a request for a non existing field
|
||||
if (isset($this->m_aData['m_oFieldsMap'][$sAttCode]))
|
||||
{
|
||||
$iIndex = $this->m_aData['m_oFieldsMap'][$sAttCode];
|
||||
$this->m_aData['m_aAllowedValues'][$iIndex] = $sHtml;
|
||||
}
|
||||
}
|
||||
|
||||
public function ToJSON()
|
||||
{
|
||||
return json_encode($this->m_aData);
|
||||
}
|
||||
|
||||
static public function FromJSON($sJSON)
|
||||
{
|
||||
$oWizHelper = new WizardHelper();
|
||||
if (get_magic_quotes_gpc())
|
||||
{
|
||||
$sJSON = stripslashes($sJSON);
|
||||
}
|
||||
$aData = json_decode($sJSON, true); // true means hash array instead of object
|
||||
$oWizHelper->m_aData = $aData;
|
||||
return $oWizHelper;
|
||||
}
|
||||
|
||||
protected function GetLinkedWizardStructure($oAttDef)
|
||||
{
|
||||
$oWizard = new UIWizard(null, $oAttDef->GetLinkedClass());
|
||||
$aWizardSteps = $oWizard->GetWizardStructure();
|
||||
$aFields = array();
|
||||
$sExtKeyToMeCode = $oAttDef->GetExtKeyToMe();
|
||||
// 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
|
||||
// the attribute 'ext_key_to_me' which is a constant in our case
|
||||
foreach($aWizardSteps as $sDummy => $aMainSteps)
|
||||
{
|
||||
// 2 entries: 'mandatory' and 'optional'
|
||||
foreach($aMainSteps as $aSteps)
|
||||
{
|
||||
// One entry for each step of the wizard
|
||||
foreach($aSteps as $sAttCode)
|
||||
{
|
||||
if ($sAttCode != $sExtKeyToMeCode)
|
||||
{
|
||||
$aFields[] = $sAttCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aFields;
|
||||
}
|
||||
|
||||
public function GetTargetClass()
|
||||
{
|
||||
return $this->m_aData['m_sClass'];
|
||||
}
|
||||
|
||||
public function GetIdForField($sFieldName)
|
||||
{
|
||||
return $this->m_aData['m_oFieldsMap'][$sFieldName];
|
||||
}
|
||||
|
||||
static function ParseJsonSet($oMe, $sLinkClass, $sExtKeyToMe, $sJsonSet)
|
||||
{
|
||||
$aSet = json_decode($sJsonSet, true); // true means hash array instead of object
|
||||
$oSet = CMDBObjectSet::FromScratch($sLinkClass);
|
||||
foreach($aSet as $aLinkObj)
|
||||
{
|
||||
$oLink = MetaModel::NewObject($sLinkClass);
|
||||
foreach($aLinkObj as $sAttCode => $value)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sLinkClass, $sAttCode);
|
||||
if (($oAttDef->IsExternalKey()) && ($value != '') )
|
||||
{
|
||||
// For external keys: load the target object so that external fields
|
||||
// get filled too
|
||||
$oTargetObj = MetaModel::GetObject($oAttDef->GetTargetClass(), $value);
|
||||
$oLink->Set($sAttCode, $oTargetObj);
|
||||
}
|
||||
$oLink->Set($sAttCode, $value);
|
||||
}
|
||||
$oLink->Set($sExtKeyToMe, $oMe->GetKey());
|
||||
$oSet->AddObject($oLink);
|
||||
}
|
||||
return $oSet;
|
||||
}
|
||||
}
|
||||
?>
|
||||
36
application/xmlpage.class.inc.php
Normal file
36
application/xmlpage.class.inc.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
require_once("../application/webpage.class.inc.php");
|
||||
/**
|
||||
* Simple web page with no includes or fancy formatting, useful to generateXML documents
|
||||
* The page adds the content-type text/XML and the encoding into the headers
|
||||
*/
|
||||
class XMLPage extends WebPage
|
||||
{
|
||||
function __construct($s_title)
|
||||
{
|
||||
parent::__construct($s_title);
|
||||
$this->add_header("Content-type: text/xml; charset=utf-8");
|
||||
$this->add_header("Cache-control: no-cache");
|
||||
$this->add_header("Content-location: export.xml");
|
||||
$this->add("<?xml version=\"1.0\" encoding=\"UTF-8\"?".">\n");
|
||||
}
|
||||
|
||||
public function output()
|
||||
{
|
||||
$this->add_header("Content-Length: ".strlen(trim($this->s_content)));
|
||||
foreach($this->a_headers as $s_header)
|
||||
{
|
||||
header($s_header);
|
||||
}
|
||||
echo trim($this->s_content);
|
||||
}
|
||||
|
||||
public function small_p($sText)
|
||||
{
|
||||
}
|
||||
|
||||
public function table($aConfig, $aData, $aParams = array())
|
||||
{
|
||||
}
|
||||
}
|
||||
?>
|
||||
305
business/ChangeMgmt.business.php
Normal file
305
business/ChangeMgmt.business.php
Normal file
@@ -0,0 +1,305 @@
|
||||
<?php
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* A Change Ticket
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizChangeTicket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Change",
|
||||
"description" => "Change ticket",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "ticket_status",
|
||||
"reconc_keys" => array("title"),
|
||||
"db_table" => "change_ticket",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/change.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Ticket Ref", "description"=>"Refence number ofr this change", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("title", array("label"=>"Title", "description"=>"Overview of the Change", "allowed_values"=>null, "sql"=>"title", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("type", array("label"=>"Change Type", "description"=>"Type of the Change", "allowed_values"=>new ValueSetEnum("Routine, Normal, Emergency"), "sql"=>"type", "default_value"=>"Routine", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("domain", array("label"=>"Domain", "description"=>"Domain for the Change", "allowed_values"=>new ValueSetEnum("Network,Server,Desktop,Application"), "sql"=>"domain", "default_value"=>"Desktop", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("reason", array("label"=>"Reason For Change", "description"=>"Reason for the Change", "allowed_values"=>null, "sql"=>"reason", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("requestor_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Requestor", "description"=>"who is requesting this change", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p WHERE p.org_id = :this->org_id'), "sql"=>"requestor_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array("org_id"))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("requestor_mail", array("label"=>"Requestor", "description"=>"mail of user requesting this change", "allowed_values"=>null, "extkey_attcode"=> 'requestor_id', "target_attcode"=>"email")));
|
||||
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("org_id", array("targetclass"=>"bizOrganization", "label"=>"Customer", "description"=>"who is impacted by the ticket", "allowed_values"=>null, "sql"=>"customer", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("customer_name", array("label"=>"Customer", "description"=>"Name of the customer impacted by this ticket", "allowed_values"=>null, "extkey_attcode"=> 'org_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("ticket_status", array("label"=>"Status", "description"=>"Status of the ticket", "allowed_values"=>new ValueSetEnum("New, Validated,Rejected,Assigned,PlannedScheduled,Approved,NotApproved,Implemented,Monitored, Closed"), "sql"=>"change_status", "default_value"=>"New", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
// SetPossibleValues("status",array("Open","Monitored","Closed"));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("creation_date", array("label"=>"Creation Date", "description"=>"Change creation date", "allowed_values"=>null, "sql"=>"creation_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
// définir une date de défaut à maintenant, alias creation ou modification du ticket
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("last_update", array("label"=>"Last Update", "description"=>"last time the Ticket was modified", "allowed_values"=>null, "sql"=>"last_update", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("start_date", array("label"=>"Start Date", "description"=>"Time the change is expected to start", "allowed_values"=>null, "sql"=>"start_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("end_date", array("label"=>"End Date", "description"=>"Date when the change is supposed to end", "allowed_values"=>null, "sql"=>"end_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("close_date", array("label"=>"Closure Date", "description"=>"Date when the Ticket was closed", "allowed_values"=>null, "sql"=>"closed_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Risk Assessment", "description"=>"Impact of the change", "allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("workgroup_id", array("targetclass"=>"bizWorkgroup", "jointype"=> "", "label"=>"Workgroup", "description"=>"which workgroup is owning ticket", "allowed_values"=>null, "sql"=>"workgroup_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("workgroup_name", array("label"=>"Workgroup", "description"=>"name of workgroup managing the Ticket", "allowed_values"=>null, "extkey_attcode"=> 'workgroup_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("agent_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Agent", "description"=>"who is managing the ticket", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p JOIN lnkContactTeam AS l ON l.contact_id=p.id JOIN bizTeam AS t ON l.team_id=t.id JOIN bizWorkgroup AS w ON w.team_id=t.id WHERE w.id = :this->workgroup_id'), "sql"=>"agent_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array('workgroup_id'))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("agent_mail", array("label"=>"Agent", "description"=>"name of agent managing the Ticket", "allowed_values"=>null, "extkey_attcode"=> 'agent_id', "target_attcode"=>"email")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("supervisorgroup_id", array("targetclass"=>"bizWorkgroup", "jointype"=> "", "label"=>"Supervisor Group", "description"=>"which workgroup is supervising ticket", "allowed_values"=>null, "sql"=>"supervisorgroup_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("supervisorgroup_name", array("label"=>"Supervisor Group", "description"=>"name of the group supervising the Ticket", "allowed_values"=>null, "extkey_attcode"=> 'supervisorgroup_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("supervisor_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Supervisor", "description"=>"who is managing the ticket", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p JOIN lnkContactTeam AS l ON l.contact_id=p.id JOIN bizTeam AS t ON l.team_id=t.id JOIN bizWorkgroup AS w ON w.team_id=t.id WHERE w.id = :this->supervisorgroup_id'), "sql"=>"supervisor_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array('supervisorgroup_id'))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("supervisor_mail", array("label"=>"Supervisor", "description"=>"name of agent supervising the Ticket", "allowed_values"=>null, "extkey_attcode"=> 'supervisor_id', "target_attcode"=>"email")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("managergroup_id", array("targetclass"=>"bizWorkgroup", "jointype"=> "", "label"=>"Manager Group", "description"=>"which workgroup is approving ticket", "allowed_values"=>null, "sql"=>"managergroup_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("managergroup_name", array("label"=>"Manager Group", "description"=>"name of workgroup approving the Ticket", "allowed_values"=>null, "extkey_attcode"=> 'managergroup_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("manager_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Manager", "description"=>"who is approving the ticket", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p JOIN lnkContactTeam AS l ON l.contact_id=p.id JOIN bizTeam AS t ON l.team_id=t.id JOIN bizWorkgroup AS w ON w.team_id=t.id WHERE w.id = :this->managergroup_id'), "sql"=>"manager_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array('managergroup_id'))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("manager_mail", array("label"=>"Manager", "description"=>"name of agent approving the Ticket", "allowed_values"=>null, "extkey_attcode"=> 'manager_id', "target_attcode"=>"email")));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("outage", array("label"=>"Planned Outage", "description"=>"Flag to define if there is a planned outage", "allowed_values"=>new ValueSetEnum("Yes,No"), "sql"=>"outage", "default_value"=>"No", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeText("change_request", array("label"=>"Change Request", "description"=>"Description of Change required", "allowed_values"=>null, "sql"=>"change_req", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("change_log", array("label"=>"Implementation Log", "description"=>"List all action performed during the change", "allowed_values"=>null, "sql"=>"change_log", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("fallback", array("label"=>"Fallback Plan", "description"=>"Instruction to come back to former situation", "allowed_values"=>null, "sql"=>"fallback", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("assignment_count", array("label"=>"Assignment Count", "description"=>"Number of times this ticket was assigned or reassigned", "allowed_values"=>null, "sql"=>"assignment_count", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("impacted_infra_manual", array("label"=>"Impacted Infrastructure", "description"=>"CIs that are impacted by this change", "linked_class"=>"lnkInfraChangeTicket", "ext_key_to_me"=>"ticket_id", "ext_key_to_remote"=>"infra_id", "allowed_values"=>null, "count_min"=>1, "count_max"=>0, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("title");
|
||||
MetaModel::Init_AddFilterFromAttribute("type");
|
||||
MetaModel::Init_AddFilterFromAttribute("domain");
|
||||
MetaModel::Init_AddFilterFromAttribute("org_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("requestor_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("ticket_status");
|
||||
MetaModel::Init_AddFilterFromAttribute("creation_date");
|
||||
MetaModel::Init_AddFilterFromAttribute("start_date");
|
||||
MetaModel::Init_AddFilterFromAttribute("last_update");
|
||||
MetaModel::Init_AddFilterFromAttribute("end_date");
|
||||
MetaModel::Init_AddFilterFromAttribute("close_date");
|
||||
MetaModel::Init_AddFilterFromAttribute("workgroup_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("workgroup_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("supervisorgroup_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("managergroup_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("supervisor_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("manager_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("agent_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("impact");
|
||||
MetaModel::Init_AddFilterFromAttribute("assignment_count");
|
||||
MetaModel::Init_AddFilterFromAttribute("outage");
|
||||
|
||||
// doit-on aussi ajouter un filtre sur les extfields lié à une extkey ? ici le name de l'agent?
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name','title', 'org_id','type','domain','requestor_id','change_request','ticket_status', 'outage','impact', 'last_update', 'start_date','end_date', 'assignment_count', 'workgroup_id','agent_id','supervisorgroup_id','supervisor_id','managergroup_id','manager_id','change_log','fallback')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'title', 'org_id', 'ticket_status','outage','start_date','type')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'title', 'org_id', 'ticket_status','type', 'outage','requestor_id','workgroup_id','agent_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'title', 'org_id', 'ticket_status','type', 'outage','workgroup_id','agent_id')); // Criteria of the advanced search form
|
||||
|
||||
// State machine
|
||||
MetaModel::Init_DefineState("New", array("label"=>"New (Unassigned)", "description"=>"Newly created ticket", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY,'org_id' => OPT_ATT_MANDATORY, 'title' => OPT_ATT_MANDATORY, 'reason' => OPT_ATT_MANDATORY, 'impacted_infra_manual' => OPT_ATT_MANDATORY,
|
||||
'assignment_count' => OPT_ATT_HIDDEN, 'end_date' => OPT_ATT_HIDDEN, 'workgroup_id' => OPT_ATT_HIDDEN, 'supervisorgroup_id' => OPT_ATT_HIDDEN, 'managergroup_id' => OPT_ATT_HIDDEN, 'supervisor_id' => OPT_ATT_HIDDEN, 'manager_id' => OPT_ATT_HIDDEN, 'agent_id' => OPT_ATT_HIDDEN )));
|
||||
MetaModel::Init_DefineState("Validated", array("label"=>"Validated", "description"=>"Ticket is validated", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY,'org_id' => OPT_ATT_READONLY,'change_request' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY, 'title' => OPT_ATT_READONLY, 'reason' => OPT_ATT_READONLY, 'impacted_infra_manual' => OPT_ATT_MANDATORY,
|
||||
'assignment_count' => OPT_ATT_HIDDEN, 'end_date' => OPT_ATT_HIDDEN, 'workgroup_id' => OPT_ATT_MUSTCHANGE, 'supervisorgroup_id' => OPT_ATT_MUSTCHANGE, 'managergroup_id' => OPT_ATT_MUSTCHANGE, 'supervisor_id' => OPT_ATT_HIDDEN, 'manager_id' => OPT_ATT_HIDDEN, 'agent_id' => OPT_ATT_HIDDEN)));
|
||||
MetaModel::Init_DefineState("Rejected", array("label"=>"Rejected", "description"=>"This ticket is not approved", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, 'org_id' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY,'assignment_count' => OPT_ATT_HIDDEN, 'end_date' => OPT_ATT_HIDDEN)));
|
||||
MetaModel::Init_DefineState("Assigned", array("label"=>"Assigned", "description"=>"Ticket is assigned", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY,'org_id' => OPT_ATT_READONLY,'change_request' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY, 'title' => OPT_ATT_READONLY, 'reason' => OPT_ATT_READONLY, 'impacted_infra_manual' => OPT_ATT_MANDATORY,
|
||||
'assignment_count' => OPT_ATT_HIDDEN, 'end_date' => OPT_ATT_HIDDEN, 'workgroup_id' => OPT_ATT_MANDATORY, 'supervisorgroup_id' => OPT_ATT_MANDATORY, 'managergroup_id' => OPT_ATT_MANDATORY, 'supervisor_id' => OPT_ATT_MUSTCHANGE, 'manager_id' => OPT_ATT_MUSTCHANGE, 'agent_id' => OPT_ATT_MUSTCHANGE)));
|
||||
|
||||
MetaModel::Init_DefineState("PlannedScheduled", array("label"=>"Planned&Scheduled", "description"=>"Evaluation is done for this change", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, 'org_id' => OPT_ATT_READONLY,'assignment_count' => OPT_ATT_HIDDEN,'start_date' => OPT_ATT_MANDATORY, 'end_date' => OPT_ATT_MANDATORY, 'impact' => OPT_ATT_MANDATORY, 'workgroup_id' => OPT_ATT_READONLY,'supervisorgroup_id' => OPT_ATT_READONLY, 'managergroup_id' => OPT_ATT_READONLY, 'supervisor_id' => OPT_ATT_MANDATORY, 'manager_id' => OPT_ATT_MANDATORY, 'agent_id' => OPT_ATT_MANDATORY, 'change_log' => OPT_ATT_MANDATORY,'fallback' => OPT_ATT_MANDATORY,'title' => OPT_ATT_READONLY, 'reason' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY,'requestor_id' => OPT_ATT_READONLY,'domain' => OPT_ATT_READONLY,'change_request' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY)));
|
||||
MetaModel::Init_DefineState("Approved", array("label"=>"Approved", "description"=>"Ticket is approved by CAB", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, 'org_id' => OPT_ATT_READONLY,'outage' => OPT_ATT_READONLY,'assignment_count' => OPT_ATT_HIDDEN,'start_date' => OPT_ATT_READONLY, 'end_date' => OPT_ATT_MANDATORY, 'impact' => OPT_ATT_READONLY, 'workgroup_id' => OPT_ATT_READONLY,'supervisorgroup_id' => OPT_ATT_READONLY, 'managergroup_id' => OPT_ATT_READONLY, 'supervisor_id' => OPT_ATT_READONLY, 'manager_id' => OPT_ATT_READONLY, 'agent_id' => OPT_ATT_MANDATORY, 'change_log' => OPT_ATT_MANDATORY,'fallback' => OPT_ATT_MANDATORY,'title' => OPT_ATT_READONLY, 'reason' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY,'requestor_id' => OPT_ATT_READONLY,'domain' => OPT_ATT_READONLY,'change_request' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY)));
|
||||
MetaModel::Init_DefineState("NotApproved", array("label"=>"Not Approved", "description"=>"Ticket has not been approved by CAB", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, 'org_id' => OPT_ATT_READONLY,'outage' => OPT_ATT_READONLY,'assignment_count' => OPT_ATT_HIDDEN,'start_date' => OPT_ATT_READONLY, 'end_date' => OPT_ATT_MANDATORY, 'impact' => OPT_ATT_READONLY, 'workgroup_id' => OPT_ATT_READONLY,'supervisorgroup_id' => OPT_ATT_READONLY, 'managergroup_id' => OPT_ATT_READONLY, 'supervisor_id' => OPT_ATT_READONLY, 'manager_id' => OPT_ATT_READONLY, 'agent_id' => OPT_ATT_MANDATORY, 'change_log' => OPT_ATT_MANDATORY,'fallback' => OPT_ATT_MANDATORY,'title' => OPT_ATT_READONLY, 'reason' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY,'requestor_id' => OPT_ATT_READONLY,'domain' => OPT_ATT_READONLY,'change_request' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY)));
|
||||
MetaModel::Init_DefineState("Implemented", array("label"=>"Implementation", "description"=>"Work is in progress for this ticket", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, 'org_id' => OPT_ATT_READONLY,'assignment_count' => OPT_ATT_HIDDEN,'start_date' => OPT_ATT_READONLY,'outage' => OPT_ATT_READONLY, 'end_date' => OPT_ATT_MANDATORY, 'impact' => OPT_ATT_READONLY, 'workgroup_id' => OPT_ATT_READONLY,'supervisorgroup_id' => OPT_ATT_READONLY, 'managergroup_id' => OPT_ATT_READONLY, 'supervisor_id' => OPT_ATT_READONLY, 'manager_id' => OPT_ATT_READONLY, 'agent_id' => OPT_ATT_MANDATORY, 'change_log' => OPT_ATT_MANDATORY,'fallback' => OPT_ATT_MANDATORY,'title' => OPT_ATT_READONLY, 'reason' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY,'requestor_id' => OPT_ATT_READONLY,'domain' => OPT_ATT_READONLY,'change_request' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY)));
|
||||
MetaModel::Init_DefineState("Monitored", array("label"=>"Monitored", "description"=>"Change performed is now monitored", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, 'org_id' => OPT_ATT_READONLY,'assignment_count' => OPT_ATT_HIDDEN,'start_date' => OPT_ATT_READONLY, 'end_date' => OPT_ATT_READONLY, 'impact' => OPT_ATT_READONLY, 'workgroup_id' => OPT_ATT_READONLY,'supervisorgroup_id' => OPT_ATT_READONLY, 'managergroup_id' => OPT_ATT_READONLY, 'supervisor_id' => OPT_ATT_READONLY, 'manager_id' => OPT_ATT_READONLY, 'agent_id' => OPT_ATT_READONLY, 'change_log' => OPT_ATT_READONLY,'fallback' => OPT_ATT_READONLY,'title' => OPT_ATT_READONLY, 'reason' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY,'requestor_id' => OPT_ATT_READONLY,'domain' => OPT_ATT_READONLY,'change_request' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY)));
|
||||
MetaModel::Init_DefineState("Closed", array("label"=>"Closed", "description"=>"Ticket is closed", "attribute_inherit"=>null, "attribute_list"=>array('name' => OPT_ATT_READONLY,'outage' => OPT_ATT_READONLY,'org_id' => OPT_ATT_READONLY,'assignment_count' => OPT_ATT_HIDDEN,'start_date' => OPT_ATT_READONLY,'end_date' => OPT_ATT_READONLY,'last_update' => OPT_ATT_READONLY,'close_date' => OPT_ATT_READONLY, 'impact' => OPT_ATT_READONLY, 'workgroup_id' => OPT_ATT_READONLY,'supervisorgroup_id' => OPT_ATT_READONLY, 'managergroup_id' => OPT_ATT_READONLY, 'supervisor_id' => OPT_ATT_READONLY, 'manager_id' => OPT_ATT_READONLY, 'agent_id' => OPT_ATT_READONLY, 'change_log' => OPT_ATT_READONLY,'fallback' => OPT_ATT_READONLY,'title' => OPT_ATT_READONLY, 'reason' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY,'requestor_id' => OPT_ATT_READONLY,'domain' => OPT_ATT_READONLY,'change_request' => OPT_ATT_READONLY,'creation_date' => OPT_ATT_READONLY)));
|
||||
|
||||
MetaModel::Init_DefineStimulus("ev_validate", new StimulusUserAction(array("label"=>"Validate this change", "description"=>"Make sure it is a valid change request")));
|
||||
MetaModel::Init_DefineStimulus("ev_reject", new StimulusUserAction(array("label"=>"Reject this change", "description"=>"This change request is rejected because it is a non valid one")));
|
||||
MetaModel::Init_DefineStimulus("ev_assign", new StimulusUserAction(array("label"=>"Assign this change", "description"=>"This change request is assigned")));
|
||||
|
||||
MetaModel::Init_DefineStimulus("ev_reopen", new StimulusUserAction(array("label"=>"Modify this change", "description"=>"Update change request to make it valid")));
|
||||
MetaModel::Init_DefineStimulus("ev_plan", new StimulusUserAction(array("label"=>"Plan this change", "description"=>"Plan and Schedule this change for validation")));
|
||||
MetaModel::Init_DefineStimulus("ev_approve", new StimulusUserAction(array("label"=>"Approve this change", "description"=>"This change is approved by CAB")));
|
||||
MetaModel::Init_DefineStimulus("ev_replan", new StimulusUserAction(array("label"=>"Update planning and schedule", "description"=>"Modify Plan and Schedule in order to have this change re-validated")));
|
||||
MetaModel::Init_DefineStimulus("ev_notapprove", new StimulusUserAction(array("label"=>"Not approve this change", "description"=>"This change is not approved by CAB")));
|
||||
MetaModel::Init_DefineStimulus("ev_implement", new StimulusUserAction(array("label"=>"Implement this change", "description"=>"Implementation pahse for current change")));
|
||||
MetaModel::Init_DefineStimulus("ev_monitor", new StimulusUserAction(array("label"=>"Monitor this change", "description"=>"Starting monitoring period for this change")));
|
||||
MetaModel::Init_DefineStimulus("ev_finish", new StimulusUserAction(array("label"=>"Close change", "description"=>"Change is done, and can be closed")));
|
||||
|
||||
MetaModel::Init_DefineTransition("New", "ev_validate", array("target_state"=>"Validated", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("New", "ev_reject", array("target_state"=>"Rejected", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Rejected", "ev_reopen", array("target_state"=>"New", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Validated", "ev_assign", array("target_state"=>"Assigned", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Assigned", "ev_plan", array("target_state"=>"PlannedScheduled", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
|
||||
MetaModel::Init_DefineTransition("PlannedScheduled", "ev_approve", array("target_state"=>"Approved", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("PlannedScheduled", "ev_notapprove", array("target_state"=>"NotApproved", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("NotApproved", "ev_replan", array("target_state"=>"PlannedScheduled", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Approved", "ev_implement", array("target_state"=>"Implemented", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Implemented", "ev_monitor", array("target_state"=>"Monitored", "actions"=>array('SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Implemented", "ev_finish", array("target_state"=>"Closed", "actions"=>array('SetClosureDate','SetLastUpDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Monitored", "ev_finish", array("target_state"=>"Closed", "actions"=>array('SetClosureDate','SetLastUpDate'), "user_restriction"=>null));
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('org_id', $oGenerator->GetOrganizationId());
|
||||
$this->Set('title', $oGenerator->GenerateString("enum(Site,Server,Line)| |enum(is down,is flip-flopping,is not responding)"));
|
||||
$this->Set('agent_id', $oGenerator->GenerateKey("bizPerson", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('ticket_status', $oGenerator->GenerateString("enum(Open,Closed,Closed,Monitored)"));
|
||||
$this->Set('start_date', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
$this->Set('last_update', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
$this->Set('end_date', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// State machine actions
|
||||
public function IncrementAssignmentCount($sStimulusCode)
|
||||
{
|
||||
$this->Set('assignment_count', $this->Get('assignment_count') + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function SetClosureDate($sStimulusCode)
|
||||
{
|
||||
$this->Set('end_date', time());
|
||||
return true;
|
||||
}
|
||||
public function SetLastUpDate($sStimulusCode)
|
||||
{
|
||||
$this->Set('last_update', time());
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ComputeValues()
|
||||
{
|
||||
$iKey = $this->GetKey();
|
||||
if ($iKey < 0)
|
||||
{
|
||||
// Object not yet in the Database
|
||||
$iKey = MetaModel::GetNextKey(get_class($this));
|
||||
}
|
||||
$sName = sprintf('C-%06d', $iKey);
|
||||
$this->Set('name', $sName);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Infra and a Change Ticket
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkInfraChangeTicket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Infra Change Ticket",
|
||||
"description" => "Infra impacted by a Change ticket",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "impact", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("impact"), // ????
|
||||
"db_table" => "infra_changeticket",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("infra_id", array("targetclass"=>"logInfra", "jointype"=> '', "label"=>"Infrastructure", "description"=>"The infrastructure impacted", "allowed_values"=>null, "sql"=>"infra_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("infra_name", array("label"=>"Infrastructure Name", "description"=>"Name of the impacted infrastructure", "allowed_values"=>null, "extkey_attcode"=> 'infra_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("ticket_id", array("targetclass"=>"bizChangeTicket", "jointype"=> '', "label"=>"Ticket", "description"=>"Ticket number", "allowed_values"=>null, "sql"=>"ticket_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("ticket_name", array("label"=>"Ticket Name", "description"=>"Name of the ticket", "allowed_values"=>null, "extkey_attcode"=> 'ticket_id', "target_attcode"=>"title")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Impact", "description"=>"Level of impact of the infra by the related ticket", "allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("infra_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("ticket_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('infra_id', 'ticket_id', 'impact')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('infra_id', 'ticket_id', 'impact')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('infra_id', 'ticket_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('infra_id', 'ticket_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('infra_id', $oGenerator->GenerateKey("logInfra", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('ticket_id', $oGenerator->GenerateKey("bizIncidentTicket", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('impact', $oGenerator->GenerateString("enum(none,mandatory,partial)"));
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any contact and a Contract
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkContactChange extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "ContactChangeLink",
|
||||
"description" => "Contact associated to a change",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "role", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("role"), // ????
|
||||
"db_table" => "contact_change",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("contact_id", array("targetclass"=>"bizContact", "jointype"=> '', "label"=>"Contact", "description"=>"The contact linked to contract", "allowed_values"=>null, "sql"=>"contact_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contact_mail", array("label"=>"Contact E-mail", "description"=>"Mail for the contact", "allowed_values"=>null, "extkey_attcode"=> 'contact_id', "target_attcode"=>"email")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("change_id", array("targetclass"=>"bizChangeTicket", "jointype"=> '', "label"=>"Change Ticket", "description"=>"Change ticket ID", "allowed_values"=>null, "sql"=>"change_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("change_number", array("label"=>"Change Ticket", "description"=>"Ticket number for this change", "allowed_values"=>null, "extkey_attcode"=> 'change_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("role", array("label"=>"Role", "description"=>"Role of this contact for this change", "allowed_values"=>null, "sql"=>"role", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("change_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("contact_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('change_id', 'contact_id', 'role')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('change_id', 'contact_id', 'role')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('change_id', 'contact_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('change_id', 'contact_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('contract_id', $oGenerator->GenerateKey("logInfra", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('contact_id', $oGenerator->GenerateKey("bizIncidentTicket", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('role', $oGenerator->GenerateString("enum(none,mandatory,partial)"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
32
business/Changes-04-Sep-2007.php
Normal file
32
business/Changes-04-Sep-2007.php
Normal file
@@ -0,0 +1,32 @@
|
||||
Changements principaux:
|
||||
- la classe AbstractObject est sortie du biz model
|
||||
- join_type remplacé par is_null_allowed (placé à la fin pour être + facile à retrouver)
|
||||
- j'ai enlevé toute la classe logLocatedObject qui était en commentaire
|
||||
- Enlevé 'address' de l'advanced search sur une location car ce n'est plus un critère de recherche possible (remplacé par country)
|
||||
- Ajouté des critères de recherche sur bizCircuit
|
||||
- Ajouté les ZList sur bizCircuit
|
||||
- Ajouté les Zlist pour bizInterface
|
||||
- Ajouté les Zlist pour lnkInfraInfra
|
||||
- Ajouté les Zlist pour lnkInfraTicket
|
||||
|
||||
Dans AbstractObject: désactivé l'affichage des contacts liés qui ne marche pas pour les tickets.
|
||||
|
||||
Bug fix ?
|
||||
- J'ai rajouté un blindage if (is_object($proposedValue) &&... dans AttributeDate::MakeRealValue mais je ne comprends pas d'où sort la classe DateTime... et pourtant il y en a...
|
||||
|
||||
Améliorations:
|
||||
- Ajouter une vérification des ZList (les attributs/critèresde recherche déclarés dans la liste existent-ils pour cet objet)
|
||||
|
||||
Ne marche pas:
|
||||
- Objets avec des clefs externes vides
|
||||
- Enums !!!!
|
||||
|
||||
Data Generator:
|
||||
Organization '1' updated.
|
||||
5 Location objects created.
|
||||
19 PC objects created.
|
||||
19 Network Device objects created.
|
||||
42 Person objects created.
|
||||
6 Incident objects created.
|
||||
17 Infra Group objects created.
|
||||
34 Infra Infra objects created.
|
||||
163
business/KEDB.business.php
Normal file
163
business/KEDB.business.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Description of known error
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizKnownError extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Known Error",
|
||||
"description" => "Error documented for a known issue",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("org_id", "name"), // inherited attributes
|
||||
"db_table" => "known_error",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/knownError.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Name", "description"=>"Name to identify this error", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("org_id", array("targetclass"=>"bizOrganization", "label"=>"Organization", "description"=>"Organization for this known error", "allowed_values"=>null, "sql"=>"cust_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("cust_name", array("label"=>"Organization", "description"=>"Company / Department owning this object", "allowed_values"=>null, "extkey_attcode"=> 'org_id', "target_attcode"=>"name")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeText("symptom", array("label"=>"Symptom", "description"=>"Description of this error", "allowed_values"=>null, "sql"=>"symptom", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("root_cause", array("label"=>"Root cause", "description"=>"Original cause for this known error", "allowed_values"=>null, "sql"=>"rootcause", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("workaround", array("label"=>"Workaround", "description"=>"Work around to fix this error", "allowed_values"=>null, "sql"=>"workaround", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("solution", array("label"=>"Solution", "description"=>"Description of this contract", "allowed_values"=>null, "sql"=>"solution", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("error_code", array("label"=>"Error Code", "description"=>"Key word to identify error", "allowed_values"=>null, "sql"=>"error_code", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("domain", array("label"=>"Domain", "description"=>"Domain for this known error, network, desktop, ...", "allowed_values"=>new ValueSetEnum("Network, Server, Application, Desktop"), "sql"=>"domain", "default_value"=>"Application", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("vendor", array("label"=>"Vendor", "description"=>"Vendor concerned by this known error", "allowed_values"=>null, "sql"=>"vendor", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("model", array("label"=>"Model", "description"=>"Model concerned by this known error, it may be an application, a device ...", "allowed_values"=>null, "sql"=>"model", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("version", array("label"=>"Version", "description"=>"Version related to model impacted by known error", "allowed_values"=>null, "sql"=>"version", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("org_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("cust_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("error_code");
|
||||
MetaModel::Init_AddFilterFromAttribute("domain");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'org_id','error_code','domain','vendor','model','version', 'symptom','root_cause','workaround','solution')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'org_id','error_code', 'symptom')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'error_code','domain')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'org_id','error_code', 'error_code','symptom')); // Criteria of the advanced search form
|
||||
|
||||
}
|
||||
|
||||
// State machine actions
|
||||
public function IncrementVersion($sStimulusCode)
|
||||
{
|
||||
$this->Set('version_number', $this->Get('version_number') + 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Infra and a Known Error
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkInfraError extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "InfraErrorLinks",
|
||||
"description" => "Infra related to a known error",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("infra_id","error_id"), // ????
|
||||
"db_table" => "infra_error_links",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("infra_id", array("targetclass"=>"logInfra", "jointype"=> '', "label"=>"Infrastructure", "description"=>"The infrastructure impacted", "allowed_values"=>null, "sql"=>"infra_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("infra_name", array("label"=>"Infrastructure Name", "description"=>"Name of the impacted infrastructure", "allowed_values"=>null, "extkey_attcode"=> 'infra_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("infra_status", array("label"=>"Status", "description"=>"Status of the impacted infrastructure", "allowed_values"=>null, "extkey_attcode"=> 'infra_id', "target_attcode"=>"status")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("error_id", array("targetclass"=>"bizKnownError", "jointype"=> '', "label"=>"Error", "description"=>"Error id", "allowed_values"=>null, "sql"=>"error_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("error_name", array("label"=>"Error Name", "description"=>"Name of the error", "allowed_values"=>null, "extkey_attcode"=> 'error_id', "target_attcode"=>"name")));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("infra_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("error_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('infra_id', 'error_id')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('infra_id', 'infra_status','error_id')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('infra_id', 'error_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('infra_id', 'error_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Contract and a Document
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkDocumentError extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "DocumentsErrorLinks",
|
||||
"description" => "A link between a document and a known error",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "link_type",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("doc_name", "error_name"),
|
||||
"db_table" => "documents_error_link",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("doc_id", array("targetclass"=>"bizDocument", "label"=>"Document", "description"=>"id of the Document", "allowed_values"=>null, "sql"=>"doc_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("doc_name", array("label"=>"Document Name", "description"=>"name of the document", "allowed_values"=>null, "extkey_attcode"=> 'doc_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("error_id", array("targetclass"=>"bizKnownError", "label"=>"Error", "description"=>"Error linked to this document", "allowed_values"=>null, "sql"=>"error_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("error_name", array("label"=>"Error Name", "description"=>"name of the linked error", "allowed_values"=>null, "extkey_attcode"=> 'error_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("link_type", array("label"=>"Link Type", "description"=>"More information", "allowed_values"=>null, "sql"=>"link_type", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("doc_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("doc_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("error_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("error_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("link_type");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('doc_id', 'error_name', 'link_type')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('doc_id', 'error_name', 'link_type')); // Attributes to be displayed for a list
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
276
business/ServiceDesk.business.php
Normal file
276
business/ServiceDesk.business.php
Normal file
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* ServiceDesk.businnes.php
|
||||
* Define business model for Service Desk module
|
||||
*
|
||||
* @package iTopBizModelSamples
|
||||
* @author Erwan Taloc <erwan.taloc@gmail.com>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* An Incident Ticket
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizServiceCall extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "ServiceCall",
|
||||
"description" => "Service Call from customer",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "call_status",
|
||||
"reconc_keys" => array("title"),
|
||||
"db_table" => "servicecall",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/serviceCall.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Service Call Ref", "description"=>"Refence identifier for this service call", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("title", array("label"=>"Title", "description"=>"Overview of the service call", "allowed_values"=>null, "sql"=>"title", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("type", array("label"=>"Type", "description"=>"Type of the Incident", "allowed_values"=>new ValueSetEnum("Network,Server,Desktop,Application"), "sql"=>"type", "default_value"=>"Server", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("org_id", array("targetclass"=>"bizOrganization", "label"=>"Customer", "description"=>"Customer concerned by this service call", "allowed_values"=>null, "sql"=>"customer", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("customer_name", array("label"=>"Customer", "description"=>"Name of the customer raising this service call", "allowed_values"=>null, "extkey_attcode"=> 'org_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("call_status", array("label"=>"Status", "description"=>"Status of the ticket", "allowed_values"=>new ValueSetEnum("New, Assigned, WorkInProgress,Resolved,Closed"), "sql"=>"call_status", "default_value"=>"New", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
// SetPossibleValues("status",array("Open","Monitored","Closed"));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("call_description", array("label"=>"Description", "description"=>"Description of the call as describe by caller", "allowed_values"=>null, "sql"=>"call_description", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("creation_date", array("label"=>"Creation date", "description"=>"Call creation date", "allowed_values"=>null, "sql"=>"creation_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
// définir une date de défaut à maintenant, alias creation ou modification du ticket
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("last_update", array("label"=>"Last update", "description"=>"last time the call was modified", "allowed_values"=>null, "sql"=>"last_update", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("next_update", array("label"=>"Next update", "description"=>"next time the Ticket is expected to be modified", "allowed_values"=>null, "sql"=>"next_update", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("end_date", array("label"=>"Closure Date", "description"=>"Date when the call was closed", "allowed_values"=>null, "sql"=>"closed_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("caller_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Caller", "description"=>"person that trigger this call", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p WHERE p.org_id = :this->org_id'), "sql"=>"caller_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array('org_id'))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("caller_mail", array("label"=>"Caller", "description"=>"Person that trigger this call", "allowed_values"=>null, "extkey_attcode"=> 'caller_id', "target_attcode"=>"email")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Impact", "description"=>"Impact for this call", "allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("workgroup_id", array("targetclass"=>"bizWorkgroup", "jointype"=> "", "label"=>"Workgroup", "description"=>"which workgroup is owning call", "allowed_values"=>null, "sql"=>"workgroup_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("workgroup_name", array("label"=>"Workgroup", "description"=>"name of workgroup managing the call", "allowed_values"=>null, "extkey_attcode"=> 'workgroup_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("agent_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Agent", "description"=>"who is managing the call", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p JOIN lnkContactTeam AS l ON l.contact_id=p.id JOIN bizTeam AS t ON l.team_id=t.id JOIN bizWorkgroup AS w ON w.team_id=t.id WHERE w.id = :this->workgroup_id'), "sql"=>"agent_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array("workgroup_id"))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("agent_mail", array("label"=>"Agent", "description"=>"mail of agent managing the call", "allowed_values"=>null, "extkey_attcode"=> 'agent_id', "target_attcode"=>"email")));
|
||||
// Comment afficher le first + last name de l'agent ? Est-ce utile d'ajouter ce champ?
|
||||
MetaModel::Init_AddAttribute(new AttributeText("action_log", array("label"=>"Action Logs", "description"=>"List all action performed during the call", "allowed_values"=>null, "sql"=>"action_log", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("severity", array("label"=>"Severity", "description"=>"Field defining the criticity for the call", "allowed_values"=>new ValueSetEnum("critical,medium,low"), "sql"=>"criticity", "default_value"=>"low", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("resolution", array("label"=>"Resolution", "description"=>"Description of the resolution", "allowed_values"=>null, "sql"=>"resolution", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("source", array("label"=>"Source", "description"=>"source type for this call", "allowed_values"=>new ValueSetEnum("phone,E-mail,Fax"), "sql"=>"source", "default_value"=>"phone", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("impacted_infra_manual", array("label"=>"Impacted Infrastructure", "description"=>"CIs that are not meeting the SLA", "linked_class"=>"lnkInfraCall", "ext_key_to_me"=>"call_id", "ext_key_to_remote"=>"infra_id", "allowed_values"=>null, "count_min"=>1, "count_max"=>0, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("related_tickets", array("label"=>"Related Incident", "description"=>"Other incident tickets related to this call", "linked_class"=>"lnkCallTicket", "ext_key_to_me"=>"call_id", "ext_key_to_remote"=>"ticket_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array(/*'impacted_infra_computed',*/ 'impacted_infra_manual'))));
|
||||
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("title");
|
||||
MetaModel::Init_AddFilterFromAttribute("type");
|
||||
MetaModel::Init_AddFilterFromAttribute("org_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("caller_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("call_status");
|
||||
MetaModel::Init_AddFilterFromAttribute("creation_date");
|
||||
MetaModel::Init_AddFilterFromAttribute("last_update");
|
||||
MetaModel::Init_AddFilterFromAttribute("end_date");
|
||||
MetaModel::Init_AddFilterFromAttribute("workgroup_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("agent_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("severity");
|
||||
MetaModel::Init_AddFilterFromAttribute("source");
|
||||
|
||||
// doit-on aussi ajouter un filtre sur les extfields lié à une extkey ? ici le name de l'agent?
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name','title', 'org_id', 'type','call_status','source', 'severity','creation_date', 'call_description', 'caller_id', 'impact', 'last_update', 'end_date', 'workgroup_id','agent_id','action_log','resolution')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'title', 'org_id', 'type','call_status','severity','creation_date')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'title', 'org_id','source', 'caller_id','type', 'call_status', 'severity','creation_date', 'last_update','end_date','agent_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'title', 'org_id', 'caller_id','type', 'call_status', 'severity','creation_date', 'last_update','end_date','agent_id')); // Criteria of the advanced search form
|
||||
|
||||
// State machine
|
||||
MetaModel::Init_DefineState("New", array("label"=>"New (Unassigned)", "description"=>"Newly created call", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, 'end_date' => OPT_ATT_HIDDEN, 'last_update' => OPT_ATT_READONLY,
|
||||
"title"=>OPT_ATT_MANDATORY, "org_id"=>OPT_ATT_MANDATORY, "caller_id"=>OPT_ATT_MANDATORY, "call_description"=>OPT_ATT_MANDATORY, "creation_date"=>OPT_ATT_MANDATORY, "workgroup_id"=>OPT_ATT_MANDATORY,
|
||||
"severity"=>OPT_ATT_MANDATORY, "agent_id"=>OPT_ATT_HIDDEN,"impacted_infra_manual"=>OPT_ATT_MANDATORY, "related_tickets"=>OPT_ATT_MUSTPROMPT)));
|
||||
MetaModel::Init_DefineState("Assigned", array("label"=>"Assigned", "description"=>"Call is assigned to somebody", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, "title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY,"source"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "call_description"=>OPT_ATT_READONLY, "creation_date"=>OPT_ATT_READONLY,'end_date' => OPT_ATT_HIDDEN, "workgroup_id"=>OPT_ATT_READONLY, "agent_id"=>OPT_ATT_MUSTCHANGE)));
|
||||
MetaModel::Init_DefineState("WorkInProgress", array("label"=>"Work In Progress", "description"=>"Work is in progress", "attribute_inherit"=>null, "attribute_list"=>array('name' => OPT_ATT_READONLY, 'end_date' => OPT_ATT_HIDDEN, 'last_update' => OPT_ATT_READONLY,
|
||||
"title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY,"source"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "call_description"=>OPT_ATT_READONLY, "creation_date"=>OPT_ATT_READONLY, "workgroup_id"=>OPT_ATT_READONLY,
|
||||
"severity"=>OPT_ATT_MANDATORY, "agent_id"=>OPT_ATT_MANDATORY,"action_log"=>OPT_ATT_MUSTPROMPT,"impacted_infra_manual"=>OPT_ATT_MANDATORY, "related_tickets"=>OPT_ATT_MUSTPROMPT)));
|
||||
MetaModel::Init_DefineState("Resolved", array("label"=>"Resolved", "description"=>"Call is resolved", "attribute_inherit"=>null, "attribute_list"=>array('name' => OPT_ATT_READONLY, 'end_date' => OPT_ATT_HIDDEN, 'last_update' => OPT_ATT_READONLY,
|
||||
"title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY, "source"=>OPT_ATT_READONLY,"caller_id"=>OPT_ATT_READONLY, "call_description"=>OPT_ATT_READONLY, "creation_date"=>OPT_ATT_READONLY, "workgroup_id"=>OPT_ATT_READONLY,
|
||||
"severity"=>OPT_ATT_READONLY, "agent_id"=>OPT_ATT_READONLY,"action_log"=>OPT_ATT_READONLY,"impacted_infra_manual"=>OPT_ATT_MANDATORY, "related_tickets"=>OPT_ATT_MUSTPROMPT, "resolution"=>OPT_ATT_MUSTCHANGE)));
|
||||
MetaModel::Init_DefineState("Closed", array("label"=>"Closed", "description"=>"Call is closed", "attribute_inherit"=>null, "attribute_list"=>array('name' => OPT_ATT_READONLY, 'end_date' => OPT_ATT_READONLY, 'last_update' => OPT_ATT_READONLY,"next_update"=>OPT_ATT_READONLY,
|
||||
"title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY,"source"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "call_description"=>OPT_ATT_READONLY, "creation_date"=>OPT_ATT_READONLY,"impact"=>OPT_ATT_READONLY,"type"=>OPT_ATT_READONLY, "workgroup_id"=>OPT_ATT_READONLY,
|
||||
"severity"=>OPT_ATT_READONLY, "agent_id"=>OPT_ATT_READONLY,"action_log"=>OPT_ATT_READONLY,"impacted_infra_manual"=>OPT_ATT_READONLY, "related_tickets"=>OPT_ATT_READONLY, "resolution"=>OPT_ATT_READONLY)));
|
||||
|
||||
MetaModel::Init_DefineStimulus("ev_assign", new StimulusUserAction(array("label"=>"Assign this call", "description"=>"Assign this call to a group and an agent")));
|
||||
MetaModel::Init_DefineStimulus("ev_reassign", new StimulusUserAction(array("label"=>"Reassign this call", "description"=>"Reassign this call to a different group and agent")));
|
||||
MetaModel::Init_DefineStimulus("ev_start_working", new StimulusUserAction(array("label"=>"Work on this call", "description"=>"Start working on this call")));
|
||||
MetaModel::Init_DefineStimulus("ev_resolve", new StimulusUserAction(array("label"=>"Resolve this call", "description"=>"Resolve this call")));
|
||||
MetaModel::Init_DefineStimulus("ev_close", new StimulusUserAction(array("label"=>"Close this call", "description"=>"Close this call")));
|
||||
|
||||
MetaModel::Init_DefineTransition("New", "ev_assign", array("target_state"=>"Assigned", "actions"=>array('SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Assigned", "ev_reassign", array("target_state"=>"Assigned", "actions"=>array('SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Assigned", "ev_start_working", array("target_state"=>"WorkInProgress", "actions"=>array('SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("WorkInProgress", "ev_reassign", array("target_state"=>"Assigned", "actions"=>array('SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("WorkInProgress", "ev_resolve", array("target_state"=>"Resolved", "actions"=>array('SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Resolved", "ev_close", array("target_state"=>"Closed", "actions"=>array('SetLastUpdate','SetClosureDate'), "user_restriction"=>null));
|
||||
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('org_id', $oGenerator->GetOrganizationId());
|
||||
$this->Set('title', $oGenerator->GenerateString("enum(Site,Server,Line)| |enum(is down,is flip-flopping,is not responding)"));
|
||||
$this->Set('agent_id', $oGenerator->GenerateKey("bizPerson", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('call_status', $oGenerator->GenerateString("enum(Open,Closed,Closed,Monitored)"));
|
||||
$this->Set('creation_date', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
$this->Set('last_update', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
$this->Set('end_date', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
}
|
||||
|
||||
// State machine actions
|
||||
|
||||
|
||||
public function SetClosureDate($sStimulusCode)
|
||||
{
|
||||
$this->Set('end_date', time());
|
||||
return true;
|
||||
}
|
||||
|
||||
public function SetLastUpdate($sStimulusCode)
|
||||
{
|
||||
$this->Set('last_update', time());
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ComputeValues()
|
||||
{
|
||||
$iKey = $this->GetKey();
|
||||
if ($iKey < 0)
|
||||
{
|
||||
// Object not yet in the Database
|
||||
$iKey = MetaModel::GetNextKey(get_class($this));
|
||||
}
|
||||
$sName = sprintf('S-%06d', $iKey);
|
||||
$this->Set('name', $sName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any ticket and a Call
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkCallTicket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Call Ticket",
|
||||
"description" => "Ticket related to a call",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "impact", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("impact"), // ????
|
||||
"db_table" => "call_ticket",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("ticket_id", array("targetclass"=>"bizIncidentTicket", "jointype"=> '', "label"=>"Related Ticket", "description"=>"The related ticket", "allowed_values"=>null, "sql"=>"ticket_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("ticket_name", array("label"=>"Related ticket", "description"=>"Name of the related ticket", "allowed_values"=>null, "extkey_attcode"=> 'ticket_id', "target_attcode"=>"title")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("call_id", array("targetclass"=>"bizServiceCall", "jointype"=> '', "label"=>"Call", "description"=>"Ticket number", "allowed_values"=>null, "sql"=>"call_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("call_name", array("label"=>"Call name", "description"=>"Name of the call", "allowed_values"=>null, "extkey_attcode"=> 'call_id', "target_attcode"=>"title")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Impact", "description"=>"Impact on the call", "allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("ticket_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("call_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('ticket_id', 'call_id', 'impact')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('ticket_id', 'call_id', 'impact')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('ticket_id', 'call_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('ticket_id', 'call_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('call_id', $oGenerator->GenerateKey("bizServiceCall", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('ticket_id', $oGenerator->GenerateKey("bizIncidentTicket", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('impact', $oGenerator->GenerateString("enum(none,mandatory,partial)"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Infra and a Call
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkInfraCall extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Infra Call",
|
||||
"description" => "Infra concerned by a call",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "impact", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("impact"), // ????
|
||||
"db_table" => "infra_call",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("infra_id", array("targetclass"=>"logInfra", "jointype"=> '', "label"=>"Infrastructure", "description"=>"The infrastructure impacted", "allowed_values"=>null, "sql"=>"infra_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("infra_name", array("label"=>"Infrastructure Name", "description"=>"Name of the impacted infrastructure", "allowed_values"=>null, "extkey_attcode"=> 'infra_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("call_id", array("targetclass"=>"bizServiceCall", "jointype"=> '', "label"=>"Call", "description"=>"Call number", "allowed_values"=>null, "sql"=>"call_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("call_name", array("label"=>"Call name", "description"=>"Name of the call", "allowed_values"=>null, "extkey_attcode"=> 'call_id', "target_attcode"=>"title")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Impact", "description"=>"Level of impact of the infra by the related ticket", "allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("infra_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("call_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('infra_id', 'call_id', 'impact')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('infra_id', 'call_id', 'impact')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('infra_id', 'call_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('infra_id', 'call_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('infra_id', $oGenerator->GenerateKey("logInfra", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('call_id', $oGenerator->GenerateKey("bizServiceCall", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('impact', $oGenerator->GenerateString("enum(none,mandatory,partial)"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
?>
|
||||
338
business/ServiceMgmt.business.php
Normal file
338
business/ServiceMgmt.business.php
Normal file
@@ -0,0 +1,338 @@
|
||||
<?php
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Description of a service provided by an organization
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizService extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Service",
|
||||
"description" => "Service provided by an organization",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
//"state_attcode" => "status",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("org_id", "name"), // inherited attributes
|
||||
"db_table" => "services",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/service.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Name", "description"=>"Name of the service", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("org_id", array("targetclass"=>"bizOrganization", "label"=>"Provider", "description"=>"Provider for this service", "allowed_values"=>null, "sql"=>"customer_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("provider_name", array("label"=>"Provider", "description"=>"name of the Provider", "allowed_values"=>null, "extkey_attcode"=> 'org_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("service_category", array("label"=>"Service Category", "description"=>"Category for this contract", "allowed_values"=>new ValueSetEnum("Server,Network,End-User,Desktop,Application"), "sql"=>"service_category", "default_value"=>"End-User", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("description", array("label"=>"Description", "description"=>"Description of this service", "allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("label"=>"Status", "description"=>"Status of the service", "allowed_values"=>new ValueSetEnum("New, Implementation,Production,Obsolete"), "sql"=>"status", "default_value"=>"New", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("type", array("label"=>"Type", "description"=>"Type of the service", "allowed_values"=>new ValueSetEnum("Hardware,Software,Support"), "sql"=>"type", "default_value"=>"Support", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("org_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("service_category");
|
||||
MetaModel::Init_AddFilterFromAttribute("type");
|
||||
MetaModel::Init_AddFilterFromAttribute("status");
|
||||
|
||||
/*
|
||||
// Life cycle
|
||||
MetaModel::Init_DefineState("New", array("label"=>"New", "description"=>"Newly created service", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Implementation", array("label"=>"Implementing", "description"=>"The service is being worked on", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Production", array("label"=>"Production", "description"=>"The service is effective in production", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Obsolete", array("label"=>"Obsolete", "description"=>"The service is no more deleivered", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
|
||||
MetaModel::Init_DefineStimulus("ev_implement", new StimulusUserAction(array("label"=>"Implement this service", "description"=>"This service is under construction")));
|
||||
MetaModel::Init_DefineStimulus("ev_move2prod", new StimulusUserAction(array("label"=>"Move to production", "description"=>"This service is now on production")));
|
||||
MetaModel::Init_DefineStimulus("ev_obsolete", new StimulusUserAction(array("label"=>"Obsolete", "description"=>"Thi service is no more delivered")));
|
||||
|
||||
MetaModel::Init_DefineTransition("New", "ev_implement", array("target_state"=>"Implementation", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Implementation", "ev_move2prod", array("target_state"=>"Production", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Production", "ev_obsolete", array("target_state"=>"Obsolete", "actions"=>array('IncrementVersion'), "user_restriction"=>null));
|
||||
*/
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'status', 'org_id','service_category','type','status','description')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'status', 'org_id','service_category','type')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'status','org_id','service_category','type')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'status','org_id','service_category','type')); // Criteria of the advanced search form
|
||||
|
||||
}
|
||||
|
||||
// State machine actions
|
||||
public function IncrementVersion($sStimulusCode)
|
||||
{
|
||||
$this->Set('version_number', $this->Get('version_number') + 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Description of a contract signed with a customer
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizContract extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Contract",
|
||||
"description" => "Contract signed by an organization",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
//"state_attcode" => "status",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("org_id", "name"), // inherited attributes
|
||||
"db_table" => "contracts",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/contract.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Name", "description"=>"Name of the contract", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("org_id", array("targetclass"=>"bizOrganization", "label"=>"Customer", "description"=>"Customer for this contract", "allowed_values"=>null, "sql"=>"customer_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("customer_name", array("label"=>"Customer", "description"=>"name of the Customer", "allowed_values"=>null, "extkey_attcode"=> 'org_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("service_id", array("targetclass"=>"bizService", "label"=>"Service", "description"=>"Provider for this contract", "allowed_values"=>null, "sql"=>"service_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("provider_name", array("label"=>"Provider", "description"=>"name of the service provider", "allowed_values"=>null, "extkey_attcode"=> 'service_id', "target_attcode"=>"provider_name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("service_name", array("label"=>"Service", "description"=>"name of the service", "allowed_values"=>null, "extkey_attcode"=> 'service_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("team_id", array("targetclass"=>"bizTeam", "label"=>"Team", "description"=>"Team managing this contract", "allowed_values"=>null, "sql"=>"team_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("team_name", array("label"=>"Team", "description"=>"name of the team managing this contract", "allowed_values"=>null, "extkey_attcode"=> 'team_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("service_level", array("label"=>"Service Level", "description"=>"Level of service for this contract", "allowed_values"=>new ValueSetEnum("Gold,Silver,Bronze"), "sql"=>"service_level", "default_value"=>"Bronze", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("cost_unit", array("label"=>"Cost Unit", "description"=>"Cost unit to compute global cost for this contract", "allowed_values"=>new ValueSetEnum("Devices,Persons,Applications,Global"), "sql"=>"cost_unit", "default_value"=>"Global", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("cost_freq", array("label"=>"Billing frequency", "description"=>"Frequency of cost for this contract", "allowed_values"=>new ValueSetEnum("Monthly,Yearly,Once"), "sql"=>"cost_freq", "default_value"=>"Once", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("cost", array("label"=>"Cost", "description"=>"Cost of this contract", "allowed_values"=>null, "sql"=>"cost", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("currency", array("label"=>"Currency", "description"=>"Currency of cost for this contract", "allowed_values"=>new ValueSetEnum("Euros,Dollars"), "sql"=>"currency", "default_value"=>"Euros", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("description", array("label"=>"Description", "description"=>"Description of this contract", "allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("move2prod_date", array("label"=>"Date of Move To Production", "description"=>"Date when the contract is on production", "allowed_values"=>null, "sql"=>"move2prod_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("end_prod", array("label"=>"Date of End Of Production", "description"=>"Date when the contract is stopped", "allowed_values"=>null, "sql"=>"end_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("label"=>"Status", "description"=>"Status of the contract", "allowed_values"=>new ValueSetEnum("New, Negotiating, Signed, Production,Finished"), "sql"=>"status", "default_value"=>"New", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("type", array("label"=>"Type", "description"=>"Type of the contract", "allowed_values"=>new ValueSetEnum("Hardware,Software,Support,Licence"), "sql"=>"type", "default_value"=>"Support", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("version_number", array("label"=>"Version", "description"=>"Revision number for this contract", "allowed_values"=>null, "sql"=>"version_number", "default_value"=>1, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("service_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("provider_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("service_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("org_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("team_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("team_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("service_level");
|
||||
MetaModel::Init_AddFilterFromAttribute("end_prod");
|
||||
MetaModel::Init_AddFilterFromAttribute("status");
|
||||
MetaModel::Init_AddFilterFromAttribute("version_number");
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("type");
|
||||
|
||||
|
||||
/*
|
||||
// Life cycle
|
||||
MetaModel::Init_DefineState("New", array("label"=>"New", "description"=>"Newly created contract", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_MANDATORY,'org_id' => OPT_ATT_MANDATORY, 'service_id' => OPT_ATT_MANDATORY,'type' => OPT_ATT_MANDATORY, 'description' => OPT_ATT_MANDATORY)));
|
||||
MetaModel::Init_DefineState("Negotiating", array("label"=>"Negotiating", "description"=>"The contract is being worked on", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY,'org_id' => OPT_ATT_READONLY)));
|
||||
MetaModel::Init_DefineState("Signed", array("label"=>"Signed", "description"=>"The contract has been signed", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array( 'name' => OPT_ATT_READONLY,'org_id' => OPT_ATT_READONLY, 'service_id' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY, 'service_level' => OPT_ATT_MANDATORY , 'cost_unit' => OPT_ATT_MANDATORY , 'cost_freq' => OPT_ATT_MANDATORY , 'cost' => OPT_ATT_MANDATORY, 'currency' => OPT_ATT_MANDATORY)));
|
||||
MetaModel::Init_DefineState("Production", array("label"=>"Production", "description"=>"The contract is effective in production", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY,'org_id' => OPT_ATT_READONLY, 'service_id' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY, 'service_level' => OPT_ATT_READONLY , 'cost_unit' => OPT_ATT_READONLY , 'cost_freq' => OPT_ATT_READONLY , 'cost' => OPT_ATT_READONLY, 'currency' => OPT_ATT_READONLY,'move2prod_date' => OPT_ATT_MUSTPROMPT,'end_prod' => OPT_ATT_MANDATORY)));
|
||||
MetaModel::Init_DefineState("Finished", array("label"=>"Finished", "description"=>"The contract is terminated", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY,'org_id' => OPT_ATT_READONLY, 'service_id' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY, 'service_level' => OPT_ATT_READONLY , 'cost_unit' => OPT_ATT_READONLY , 'cost_freq' => OPT_ATT_READONLY , 'cost' => OPT_ATT_READONLY, 'currency' => OPT_ATT_READONLY,'move2prod_date' => OPT_ATT_READONLY,'end_prod' => OPT_ATT_READONLY,'team_id' => OPT_ATT_READONLY,'description' => OPT_ATT_READONLY)));
|
||||
|
||||
MetaModel::Init_DefineStimulus("ev_negociate", new StimulusUserAction(array("label"=>"Negotiate this contract", "description"=>"This version of the contract is published")));
|
||||
MetaModel::Init_DefineStimulus("ev_sign", new StimulusUserAction(array("label"=>"Sign this contract", "description"=>"This contract is being signed")));
|
||||
MetaModel::Init_DefineStimulus("ev_begin", new StimulusUserAction(array("label"=>"Move to production", "description"=>"The contract becomes applicable in production")));
|
||||
MetaModel::Init_DefineStimulus("ev_terminate", new StimulusUserAction(array("label"=>"Ends this contract", "description"=>"The contract is ending")));
|
||||
|
||||
MetaModel::Init_DefineTransition("New", "ev_negociate", array("target_state"=>"Negotiating", "actions"=>array('IncrementVersion'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Negotiating", "ev_sign", array("target_state"=>"Signed", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Negotiating", "ev_terminate", array("target_state"=>"Finished", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Signed", "ev_begin", array("target_state"=>"Production", "actions"=>array('SetProdDate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Signed", "ev_terminate", array("target_state"=>"Finished", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Production", "ev_terminate", array("target_state"=>"Finished", "actions"=>array(), "user_restriction"=>null));
|
||||
*/
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'status', 'org_id', 'service_id','provider_name','type','description','team_id','service_level','cost','currency','cost_unit','cost_freq','move2prod_date','end_prod', 'version_number')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'status', 'org_id', 'service_id','provider_name','service_name','service_level','type')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'status','service_id','provider_name','team_name','service_level','type')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'status','service_id','team_name', 'service_level', 'org_id')); // Criteria of the advanced search form
|
||||
|
||||
}
|
||||
|
||||
// State machine actions
|
||||
public function IncrementVersion($sStimulusCode)
|
||||
{
|
||||
$this->Set('version_number', $this->Get('version_number') + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function SetProdDate($sStimulusCode)
|
||||
{
|
||||
$this->Set('move2prod_date', time());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Infra and a Contract
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkInfraContract extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "InfraContractLinks",
|
||||
"description" => "Infra covered by a contract",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "coverage", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("infra_id","contract_id"), // ????
|
||||
"db_table" => "infra_contract_links",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("infra_id", array("targetclass"=>"logInfra", "jointype"=> '', "label"=>"Infrastructure", "description"=>"The infrastructure impacted", "allowed_values"=>null, "sql"=>"infra_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("infra_name", array("label"=>"Infrastructure Name", "description"=>"Name of the impacted infrastructure", "allowed_values"=>null, "extkey_attcode"=> 'infra_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("infra_status", array("label"=>"Status", "description"=>"Status of the impacted infrastructure", "allowed_values"=>null, "extkey_attcode"=> 'infra_id', "target_attcode"=>"status")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("contract_id", array("targetclass"=>"bizContract", "jointype"=> '', "label"=>"Contract", "description"=>"Contract id", "allowed_values"=>null, "sql"=>"contract_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contract_name", array("label"=>"Contract Name", "description"=>"Name of the contract", "allowed_values"=>null, "extkey_attcode"=> 'contract_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("coverage", array("label"=>"Coverage", "description"=>"coverage for the given infra", "allowed_values"=>null, "sql"=>"coverage", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("service_level", array("label"=>"Service Level", "description"=>"service level for the given infra", "allowed_values"=>null, "sql"=>"sla", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("infra_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("contract_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('infra_id', 'contract_id', 'coverage','service_level')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('infra_id', 'infra_status','contract_id' , 'coverage','service_level')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('infra_id', 'contract_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('infra_id', 'contract_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any contact and a Contract
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkContactContract extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "ContactContractLink",
|
||||
"description" => "Contact associated to a contract",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "role", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("role"), // ????
|
||||
"db_table" => "contact_Contract",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("contact_id", array("targetclass"=>"bizContact", "jointype"=> '', "label"=>"Contact", "description"=>"The contact linked to contract", "allowed_values"=>null, "sql"=>"contact_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contact_mail", array("label"=>"Contact E-mail", "description"=>"Mail for the contact", "allowed_values"=>null, "extkey_attcode"=> 'contact_id', "target_attcode"=>"email")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("contract_id", array("targetclass"=>"bizContract", "jointype"=> '', "label"=>"Contract", "description"=>"Contract ID", "allowed_values"=>null, "sql"=>"contract_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contract_name", array("label"=>"Contract Name", "description"=>"Name of the contract", "allowed_values"=>null, "extkey_attcode"=> 'contract_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("role", array("label"=>"Role", "description"=>"Role of this contact for this contract", "allowed_values"=>null, "sql"=>"role", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("contract_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("contact_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('contract_id', 'contact_id', 'role')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('contract_id', 'contact_id', 'role')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('contract_id', 'contact_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('contract_id', 'contact_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('contract_id', $oGenerator->GenerateKey("logInfra", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('contact_id', $oGenerator->GenerateKey("bizIncidentTicket", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('role', $oGenerator->GenerateString("enum(none,mandatory,partial)"));
|
||||
}
|
||||
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Contract and a Document
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkDocumentContract extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "DocumentsContractLinks",
|
||||
"description" => "A link between a document and another contract",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "link_type",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("doc_name", "contract_name"),
|
||||
"db_table" => "documents_contracts",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("doc_id", array("targetclass"=>"bizDocument", "label"=>"Document", "description"=>"id of the Document", "allowed_values"=>null, "sql"=>"doc_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("doc_name", array("label"=>"Document Name", "description"=>"name of the document", "allowed_values"=>null, "extkey_attcode"=> 'doc_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("contract_id", array("targetclass"=>"bizContract", "label"=>"Contract", "description"=>"Contract linked to this document", "allowed_values"=>null, "sql"=>"contract_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contract_name", array("label"=>"Contract Name", "description"=>"name of the linked contract", "allowed_values"=>null, "extkey_attcode"=> 'contract_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("link_type", array("label"=>"Link Type", "description"=>"More information", "allowed_values"=>null, "sql"=>"link_type", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("doc_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("doc_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("contract_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("contract_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("link_type");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('doc_id', 'contract_name', 'link_type')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('doc_id', 'contract_name', 'link_type')); // Attributes to be displayed for a list
|
||||
}
|
||||
}
|
||||
|
||||
// require_once('ServiceRequest.business.php');
|
||||
|
||||
?>
|
||||
184
business/ServiceRequest.business.php
Normal file
184
business/ServiceRequest.business.php
Normal file
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Description of a service request
|
||||
*
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizServiceRequest extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "ServiceRequest",
|
||||
"description" => "Service request",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("org_id", "name"), // inherited attributes
|
||||
"db_table" => "serviceRequests",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/serviceRequest.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Request Ref", "description"=>"Refence number ofr this service request", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("title", array("label"=>"Title", "description"=>"Overview of the Service Request", "allowed_values"=>null, "sql"=>"title", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("org_id", array("targetclass"=>"bizOrganization", "label"=>"Customer", "description"=>"Customer for this service request", "allowed_values"=>null, "sql"=>"customer_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("customer_name", array("label"=>"Customer", "description"=>"name of the Customer", "allowed_values"=>null, "extkey_attcode"=> 'org_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("description", array("label"=>"Description", "description"=>"Description of this service request", "allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("label"=>"Status", "description"=>"Status of the service request", "allowed_values"=>new ValueSetEnum("Open,approved,rejected,assigned,pending,closed"), "sql"=>"status", "default_value"=>"Open", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("requester_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Requester", "description"=>"person that trigger service request", "allowed_values"=>null, "sql"=>"requester_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("requester_mail", array("label"=>"Requester", "description"=>"Person that trigger this service request", "allowed_values"=>null, "extkey_attcode"=> 'requester_id', "target_attcode"=>"email")));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("priority", array("label"=>"Priority", "description"=>"Field defining the priority for this service request", "allowed_values"=>new ValueSetEnum("critical,medium,low"), "sql"=>"priority", "default_value"=>"low", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("source", array("label"=>"Source", "description"=>"source type for this call", "allowed_values"=>new ValueSetEnum("phone,E-mail,Fax"), "sql"=>"source", "default_value"=>"phone", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("coordinator_id", array("targetclass"=>"bizWorkgroup", "jointype"=> "", "label"=>"Coordinator", "description"=>"which workgroup is controlling this request", "allowed_values"=>null, "sql"=>"coordinator_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("coordinator_name", array("label"=>"Coordinator", "description"=>"name of workgroup coordinating this service request", "allowed_values"=>null, "extkey_attcode"=> 'coordinator_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("agent_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Coordinator Agent", "description"=>"who is managing the ticket", "allowed_values"=>null, "sql"=>"agent_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array("coordinator_id"))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("agent_mail", array("label"=>"Coordinator Agent", "description"=>"mail of agent coordinating this service request", "allowed_values"=>null, "extkey_attcode"=> 'agent_id', "target_attcode"=>"email")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("org_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("requester_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("priority");
|
||||
MetaModel::Init_AddFilterFromAttribute("coordinator_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("agent_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("status");
|
||||
MetaModel::Init_AddFilterFromAttribute("source");
|
||||
|
||||
|
||||
/*
|
||||
// Life cycle
|
||||
MetaModel::Init_DefineState("New", array("label"=>"New", "description"=>"Newly created service", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Implementation", array("label"=>"Implementing", "description"=>"The service is being worked on", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Production", array("label"=>"Production", "description"=>"The service is effective in production", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Obsolete", array("label"=>"Obsolete", "description"=>"The service is no more deleivered", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
|
||||
MetaModel::Init_DefineStimulus("ev_implement", new StimulusUserAction(array("label"=>"Implement this service", "description"=>"This service is under construction")));
|
||||
MetaModel::Init_DefineStimulus("ev_move2prod", new StimulusUserAction(array("label"=>"Move to production", "description"=>"This service is now on production")));
|
||||
MetaModel::Init_DefineStimulus("ev_obsololete", new StimulusUserAction(array("label"=>"Obsolete", "description"=>"Thi service is no more delivered")));
|
||||
|
||||
MetaModel::Init_DefineTransition("New", "ev_implement", array("target_state"=>"Implementation", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Implementation", "ev_move2prod", array("target_state"=>"Production", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Production", "ev_obsolete", array("target_state"=>"Obsolete", "actions"=>array('IncrementVersion'), "user_restriction"=>null));
|
||||
*/
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'title','status', 'org_id','priority','requester_id','description','source','coordinator_id','agent_id')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'title','status', 'org_id','priority')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'status','org_id','priority','requester_id','source','coordinator_id','agent_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'status','org_id','priority','requester_id','source','coordinator_id','agent_id')); // Criteria of the advanced search form
|
||||
|
||||
}
|
||||
|
||||
// State machine actions
|
||||
public function IncrementVersion($sStimulusCode)
|
||||
{
|
||||
$this->Set('version_number', $this->Get('version_number') + 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Description of a service item
|
||||
*
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizServiceItem extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "ServiceItem",
|
||||
"description" => "Service Item",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("request_id", "name"), // inherited attributes
|
||||
"db_table" => "serviceItems",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Request Ref", "description"=>"Refence number for this service item", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("title", array("label"=>"Title", "description"=>"Overview of the Service item", "allowed_values"=>null, "sql"=>"title", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("request_id", array("targetclass"=>"bizServiceRequest", "label"=>"Service Request", "description"=>"Corresponding service request", "allowed_values"=>null, "sql"=>"request_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("request_name", array("label"=>"Service Request", "description"=>"name of the request", "allowed_values"=>null, "extkey_attcode"=> 'request_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("contract_id", array("targetclass"=>"bizContract", "label"=>"Service", "description"=>"Corresponding service", "allowed_values"=>null, "sql"=>"contract_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contract_name", array("label"=>"Service Name", "description"=>"name of the service", "allowed_values"=>null, "extkey_attcode"=> 'contract_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("description", array("label"=>"Description", "description"=>"Description of this service request", "allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("label"=>"Status", "description"=>"Status of the service request", "allowed_values"=>new ValueSetEnum("Open,approved,rejected,assigned,pending,closed"), "sql"=>"status", "default_value"=>"Open", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("priority", array("label"=>"Priority", "description"=>"priority corresponding to service request", "allowed_values"=>null, "extkey_attcode"=> 'request_id', "target_attcode"=>"priority")));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("comment", array("label"=>"Comment", "description"=>"Comment of this service item", "allowed_values"=>null, "sql"=>"comment", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("workgroup_id", array("targetclass"=>"bizWorkgroup", "jointype"=> "", "label"=>"Workgroup", "description"=>"which workgroup working on this service item", "allowed_values"=>null, "sql"=>"workgroup_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("workgroup_name", array("label"=>"Workgroup", "description"=>"name of workgroup working on this service item", "allowed_values"=>null, "extkey_attcode"=> 'workgroup_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("agent_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Coordinator Agent", "description"=>"who is managing the service item", "allowed_values"=>null, "sql"=>"agent_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array("workgroup_id"))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("agent_mail", array("label"=>"Agent", "description"=>"mail of agent coordinating this service item", "allowed_values"=>null, "extkey_attcode"=> 'agent_id', "target_attcode"=>"email")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("request_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("contract_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("priority");
|
||||
MetaModel::Init_AddFilterFromAttribute("workgroup_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("agent_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("status");
|
||||
MetaModel::Init_AddFilterFromAttribute("priority");
|
||||
|
||||
|
||||
/*
|
||||
// Life cycle
|
||||
MetaModel::Init_DefineState("New", array("label"=>"New", "description"=>"Newly created service", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Implementation", array("label"=>"Implementing", "description"=>"The service is being worked on", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Production", array("label"=>"Production", "description"=>"The service is effective in production", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
MetaModel::Init_DefineState("Obsolete", array("label"=>"Obsolete", "description"=>"The service is no more deleivered", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array()));
|
||||
|
||||
MetaModel::Init_DefineStimulus("ev_implement", new StimulusUserAction(array("label"=>"Implement this service", "description"=>"This service is under construction")));
|
||||
MetaModel::Init_DefineStimulus("ev_move2prod", new StimulusUserAction(array("label"=>"Move to production", "description"=>"This service is now on production")));
|
||||
MetaModel::Init_DefineStimulus("ev_obsololete", new StimulusUserAction(array("label"=>"Obsolete", "description"=>"Thi service is no more delivered")));
|
||||
|
||||
MetaModel::Init_DefineTransition("New", "ev_implement", array("target_state"=>"Implementation", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Implementation", "ev_move2prod", array("target_state"=>"Production", "actions"=>array(), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Production", "ev_obsolete", array("target_state"=>"Obsolete", "actions"=>array('IncrementVersion'), "user_restriction"=>null));
|
||||
*/
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'title','request_id','contract_id','status','priority','description','comment','workgroup_id','agent_id')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'title','status', 'contract_id','priority')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name','request_id','contract_id','status','priority','workgroup_id','agent_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name','request_id','contract_id','status','priority','workgroup_id','agent_id')); // Criteria of the advanced search form
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
?>
|
||||
261
business/business_itopbegins.class.inc.php
Normal file
261
business/business_itopbegins.class.inc.php
Normal file
@@ -0,0 +1,261 @@
|
||||
<?php
|
||||
|
||||
require_once('../core/MyHelpers.class.inc.php');
|
||||
require_once('../core/cmdbobject.class.inc.php');
|
||||
|
||||
/**
|
||||
* business_itopbegins.class.inc.php
|
||||
* User defined objects, for unit testing
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Business implementation demo
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbContact extends CMDBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "klassContact",
|
||||
"description" => "klass contact description",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "att_contact_name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("att_contact_name"),
|
||||
"db_table" => "contact",
|
||||
"db_key_field" => "contactid",
|
||||
"db_finalclass_field" => "actualclass",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("att_contact_name", array("label"=>"name of the contact", "description"=>"blah", "allowed_values"=>null, "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array(), "sql"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("att_contact_availability", array("label"=>"degree of availability in percent", "description"=>"blah", "allowed_values"=>null, "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array(), "sql"=>"availability")));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("start_date", array("label"=>"Starting date", "description"=>"Incident starting date", "allowed_values"=>null, "sql"=>"start_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("att_contact_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("att_contact_availability");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbPerson extends cmdbContact
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$oValsDunsNumber = new ValueSetObjects("cmdbCompany: att_company_dunsnumber Begins with '$[duns_prm::]'", "att_company_dunsnumber", array("att_company_dunsnumber"=>true));
|
||||
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "klassPerson",
|
||||
"description" => "klass person description",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "att_contact_name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("att_contact_name"),
|
||||
"db_table" => "person",
|
||||
"db_key_field" => "personid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("att_person_email", array("label"=>"iMaile", "description"=>"imelle", "allowed_values"=>$oValsDunsNumber, "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array(), "sql"=>"email")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("att_person_name", array("label"=>"secName", "description"=>"secondary name", "allowed_values"=>new ValueSetEnum(array("nom1", "nom2", "nom10", "no", "noms", "")), "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array(), "sql"=>"name")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("att_person_email");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbSubcontractor extends cmdbPerson
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "klassSubcontractor",
|
||||
"description" => "klass subcontractor description",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "att_contact_name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("att_contact_name"),
|
||||
"db_table" => "subcontractor",
|
||||
"db_key_field" => "subcontractorid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("att_contractinfo", array("label"=>"contract info", "description"=>"blah", "allowed_values"=>null, "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array(), "sql"=>"contractinfo")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("ext_subcontractor_provider", array("label"=>"ssii", "description"=>"blah", "allowed_values"=>null, "sql"=>"provider", "targetclass"=>"cmdbProvider", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("extatt_subcontractor_provider_ref", array("label"=>"ref", "description"=>"blah", "allowed_values"=>null, "extkey_attcode"=>"ext_subcontractor_provider", "target_attcode"=>"att_provider_ref")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("ext_subcontractor_tutor", array("label"=>"tutor", "description"=>"blah", "allowed_values"=>null, "sql"=>"tutor", "targetclass"=>"cmdbPerson", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("extatt_subcontractor_tutor_email", array("label"=>"tutor email", "description"=>"blah", "allowed_values"=>null, "extkey_attcode"=>"ext_subcontractor_tutor", "target_attcode"=>"att_person_email")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("extatt_subcontractor_tutor_secondname", array("label"=>"2ndname (ext field)", "description"=>"blah", "allowed_values"=>null, "extkey_attcode"=>"ext_subcontractor_tutor", "target_attcode"=>"att_person_name")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("extatt_subcontractor_tutor_secondname");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbCrowd extends cmdbObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "klassCrowd",
|
||||
"description" => "klass crowd description",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "att_crowd_peoplecount",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("att_crowd_peoplecount"),
|
||||
"db_table" => "crowd",
|
||||
"db_key_field" => "crowdid",
|
||||
"db_finalclass_field" => "crowdclass",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("att_crowd_peoplecount", array("label"=>"people count", "description"=>"blah", "allowed_values"=>null, "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array(), "sql"=>"peoplecount")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("att_crowd_peoplecount");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbCompany extends cmdbCrowd
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "klassCompany",
|
||||
"description" => "klass company description",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "att_company_dunsnumber",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("att_company_dunsnumber"),
|
||||
"db_table" => "company",
|
||||
"db_key_field" => "companyid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("att_company_dunsnumber", array("label"=>"duns number", "description"=>"blah", "allowed_values"=>null, "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array(), "sql"=>"dunsnumber")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("att_company_dunsnumber");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbProvider extends cmdbCompany
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "klassProvider",
|
||||
"description" => "klass provider description",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "att_provider_ref",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("att_provider_ref"),
|
||||
"db_table" => "provider",
|
||||
"db_key_field" => "providerid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("att_provider_ref", array("label"=>"provider ref", "description"=>"blah", "allowed_values"=>null, "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array(), "sql"=>"providerref")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("att_provider_ref");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
366
business/business_test.class.inc.php
Normal file
366
business/business_test.class.inc.php
Normal file
@@ -0,0 +1,366 @@
|
||||
<?php
|
||||
|
||||
require_once('../core/MyHelpers.class.inc.php');
|
||||
require_once('../core/cmdbobject.class.inc.php');
|
||||
|
||||
/**
|
||||
* business_test.class.inc.php
|
||||
* User defined objects, for unit testing
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Business implementation demo
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MetaModel::RegisterRelation("Potes", array("description"=>"ceux dont l'email ressemble au mien", "verb_down"=>"est pote de", "verb_up"=>"est pote de"));
|
||||
|
||||
|
||||
MetaModel::RegisterZList("list1", array("description"=>"une premiere list, just for fun", "type"=>"attributes"));
|
||||
MetaModel::RegisterZList("list2", array("description"=>"la secunda e meliora", "type"=>"attributes"));
|
||||
MetaModel::RegisterZList("list3", array("description"=>"la variante qui tue", "type"=>"filters"));
|
||||
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbObjectHomeMade extends cmdbObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "anyObject",
|
||||
"description" => "std object",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(""),
|
||||
"db_table" => "",
|
||||
"db_key_field" => "",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
}
|
||||
|
||||
public static function GetRelationQueries($sRelCode)
|
||||
{
|
||||
//trigger_error("GetRelationQueries: cmdbObjectHomeMade");
|
||||
switch ($sRelCode)
|
||||
{
|
||||
case "Potes":
|
||||
$aRels = array("xxxx" => array("sQuery"=>"cmdbContact: pkey = 40", "bPropagate"=>true, "iDistance"=>3));
|
||||
return $aRels;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbContact extends cmdbObjectHomeMade
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Contact",
|
||||
"description" => "Un object que l'on peut communiquer avec",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "etat",
|
||||
"reconc_keys" => array("name"),
|
||||
"db_table" => "contact",
|
||||
"db_key_field" => "contactid",
|
||||
"db_finalclass_field" => "actualclass",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("etat", array("label"=>"l'etat", "description"=>"les etats d'ame d'eric", "allowed_values"=>new ValueSetEnum('justborn, 15, 21'), "sql"=>"etat", "default_value"=>"justborn", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"nom", "description"=>"ze equipe", "allowed_values"=>null, "sql"=>"name", "default_value"=>"XXXX", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("email", array("label"=>"iMaile", "description"=>"imelle", "allowed_values"=>null, "sql"=>"email", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("owner", array("label"=>"owned by", "description"=>"organization owning the team", "allowed_values"=>null, "sql"=>"ownerorg", "targetclass"=>"cmdbOrga", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("ownername", array("label"=>"owned by", "description"=>"name of organization owning the team", "allowed_values"=>null, "extkey_attcode"=>"owner", "target_attcode"=>"_name_")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("ownertnut", array("label"=>"owntnut", "description"=>"blah tnut blah", "allowed_values"=>null, "extkey_attcode"=>"owner", "target_attcode"=>"_dunsnumber_")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSet("myworkshops", array("label"=>"held workshops", "description"=>"blah tnut blah", "depends_on"=>array(), "linked_class"=>"cmdbLiens", "ext_key_to_me"=>"tocontact", "count_min"=>1, "count_max"=>10, "allowed_values"=>null)));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("owner");
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("ownername");
|
||||
|
||||
MetaModel::Init_SetZListItems("list1", array("name", "email"));
|
||||
MetaModel::Init_SetZListItems("list2", array());
|
||||
MetaModel::Init_SetZListItems("list3", array("ownername"));
|
||||
|
||||
MetaModel::Init_DefineState("justborn", array("label"=>"just born", "description"=>"too young to die", "attribute_inherit"=>null, "attribute_list"=>array("owner"=>OPT_ATT_MANDATORY)));
|
||||
MetaModel::Init_DefineState("15", array("label"=>"student", "description"=>"stupid age", "attribute_inherit"=>"justborn", "attribute_list"=>array("owner"=>OPT_ATT_MUSTPROMPT, "email"=>OPT_ATT_MUSTPROMPT)));
|
||||
MetaModel::Init_DefineState("21", array("label"=>"old", "description"=>"one foot in the grave", "attribute_inherit"=>"15", "attribute_list"=>array("email"=>OPT_ATT_READONLY|OPT_ATT_MUSTCHANGE)));
|
||||
|
||||
MetaModel::Init_DefineStimulus("toschool", new StimulusUserAction(array("label"=>"go to school", "description"=>"start learning stupid things")));
|
||||
MetaModel::Init_DefineStimulus("raise", new StimulusUserAction(array("label"=>"grow!", "description"=>"eat tons of BigMACs")));
|
||||
|
||||
MetaModel::Init_DefineTransition("justborn", "toschool", array("target_state"=>"15", "actions"=>array('MyLifecycleHandler', 'MyLifecycleHandler2'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("15", "raise", array("target_state"=>"21", "actions"=>null, "user_restriction"=>null));
|
||||
}
|
||||
|
||||
public static function GetRelationQueries($sRelCode)
|
||||
{
|
||||
//trigger_error("GetRelationQueries: cmdbContact");
|
||||
switch ($sRelCode)
|
||||
{
|
||||
case "Potes":
|
||||
$aRels = array(
|
||||
"zz1" => array("sQuery"=>"cmdbContact: name Begins with '\$[this.name::]' AND pkey != \$[this.pkey::]", "bPropagate"=>false, "iDistance"=>3),
|
||||
"zz2" => array("sQuery"=>"cmdbContact: owner = \$[this.owner::] AND owner != 2", "bPropagate"=>false, "iDistance"=>3),
|
||||
);
|
||||
return array_merge($aRels, parent::GetRelationQueries($sRelCode));
|
||||
}
|
||||
}
|
||||
|
||||
public function MyLifecycleHandler($sStimulusCode)
|
||||
{
|
||||
echo "<p>youhou!</p>";
|
||||
return true;
|
||||
}
|
||||
public function MyLifecycleHandler2($sStimulusCode)
|
||||
{
|
||||
echo "<p>... les papous...</p>";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbTeam extends cmdbContact
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Equipado",
|
||||
"description" => "Un regroupement de gens",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "email",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("email"),
|
||||
"db_table" => "team",
|
||||
"db_key_field" => "teamid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_OverloadAttributeParams("email", array("label"=>"email2", "description"=>"emailleu22"));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("headcount", array("label"=>"nombre", "description"=>"combien ils sont", "allowed_values"=>null, "sql"=>"headcount", "default_value"=>654321, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("headcount");
|
||||
|
||||
MetaModel::Init_SetZListItems("noneditable", array("name"));
|
||||
}
|
||||
|
||||
public function ComputeValues()
|
||||
{
|
||||
//echo "Set(), function ComputeValues has been found for ".get_class($this)."<br/>\n";
|
||||
$this->Set("name", $this->Get("email")." and ".$this->Get("headcount"));
|
||||
}
|
||||
|
||||
public static function GetRelationQueries($sRelCode)
|
||||
{
|
||||
//trigger_error("GetRelationQueries: cmdbTeam");
|
||||
switch ($sRelCode)
|
||||
{
|
||||
case "Potes":
|
||||
//$aRels = array("Relies on" => array("sQuery"=>"cmdbContact: name Begins with 'Louis'", "bPropagate"=>false, "iDistance"=>3));
|
||||
return array_merge(array(), parent::GetRelationQueries($sRelCode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbOrga extends cmdbObjectHomeMade
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Organization",
|
||||
"description" => "Une entite qui possede des choses",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "_name_",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("_name_"),
|
||||
"db_table" => "organization",
|
||||
"db_key_field" => "orgid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("_name_", array("label"=>"namo", "description"=>"official company name", "allowed_values"=>null, "sql"=>"name", "default_value"=>"XXXX", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("_status_", array("label"=>"step", "description"=>"step or status, etc.", "allowed_values"=>null, "sql"=>"status", "default_value"=>"XXXX", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("_dunsnumber_", array("label"=>"duns debile number", "description"=>"une bonne idee a OVSD", "allowed_values"=>null, "sql"=>"dunsnumber", "default_value"=>99007, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
// not yet allowed MetaModel::Init_AddAttribute(new AttributeInteger("_dunsnumberBY2_", array("label"=>"dummy duns", "description"=>"deux fois plus debile", "allowed_values"=>null, "sql"=>"dunsnumber * 3.141592654")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("_name_");
|
||||
|
||||
MetaModel::Init_SetZListItems("list1", array("_status_"));
|
||||
MetaModel::Init_SetZListItems("list2", array());
|
||||
MetaModel::Init_SetZListItems("list3", array("_name_"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbLiens extends cmdbObjectHomeMade
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Liens_entre_contacts_et_workshop",
|
||||
"description" => "Une entite qui lie des contacts et workshops",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "function",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("function"),
|
||||
"db_table" => "role_ws",
|
||||
"db_key_field" => "linkid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("function", array("label"=>"fonction", "description"=>"la fonction...", "allowed_values"=>null, "sql"=>"function", "default_value"=>"XXXX", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("a1", array("label"=>"a1", "description"=>"a1", "allowed_values"=>null, "sql"=>"a1", "default_value"=>"XXXX", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("a2", array("label"=>"a1", "description"=>"a2", "allowed_values"=>null, "sql"=>"a2", "default_value"=>"XXXX", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
// What makes it being a link...
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("toworkshop", array("label"=>"participates in", "description"=>"workshop in wich the person is participating", "allowed_values"=>null, "sql"=>"ws_id", "targetclass"=>"cmdbWorkshop", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("ws_info", array("label"=>"name", "description"=>"namedescription", "allowed_values"=>null, "extkey_attcode"=>"toworkshop", "target_attcode"=>"namitus")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("tocontact", array("label"=>"is held by", "description"=>"people involved in that mess", "allowed_values"=>null, "sql"=>"contactid", "targetclass"=>"cmdbContact", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contact_info", array("label"=>"name", "description"=>"namedescription", "allowed_values"=>null, "extkey_attcode"=>"tocontact", "target_attcode"=>"name")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("function");
|
||||
|
||||
MetaModel::Init_SetZListItems("list1", array("toworkshop", "contact_info"));
|
||||
MetaModel::Init_SetZListItems("list2", array("function"));
|
||||
MetaModel::Init_SetZListItems("list3", array("function"));
|
||||
}
|
||||
|
||||
public static function GetRelationQueries($sRelCode)
|
||||
{
|
||||
throw new CoreException("GetRelationQueries: cmdbLiens");
|
||||
return array("Relies on" => array("sQuery"=>"", "bPropagate"=>true, "iDistance"=>3));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* blah blah
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class cmdbWorkshop extends cmdbObjectHomeMade
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Workshop",
|
||||
"description" => "Une entite qui pond des theories insensees",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "namitus",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("namitus"),
|
||||
"db_table" => "workshop",
|
||||
"db_key_field" => "ws_id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("namitus", array("label"=>"namo", "description"=>"nom imbitique pour pondeurs de debilites", "allowed_values"=>null, "sql"=>"name", "default_value"=>"XXXX", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("namitus");
|
||||
|
||||
MetaModel::Init_SetZListItems("list1", array("namitus"));
|
||||
MetaModel::Init_SetZListItems("list2", array());
|
||||
MetaModel::Init_SetZListItems("list3", array("namitus"));
|
||||
}
|
||||
|
||||
public static function GetRelationQueries($sRelCode)
|
||||
{
|
||||
throw new CoreException("GetRelationQueries: cmdbWorkshop");
|
||||
return array("Relies on" => array("sQuery"=>"", "bPropagate"=>true, "iDistance"=>3));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
4845
business/data.samples.inc.php
Normal file
4845
business/data.samples.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
372
business/incidentMgmt.business.php
Normal file
372
business/incidentMgmt.business.php
Normal file
@@ -0,0 +1,372 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* incident<business<php
|
||||
* Define business model for incident mgmt module
|
||||
*
|
||||
* @package iTopBizModelSamples
|
||||
* @author Erwan Taloc <erwan.taloc@gmail.com>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* An Incident Ticket
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizIncidentTicket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Incident",
|
||||
"description" => "Incident ticket",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "ticket_status",
|
||||
"reconc_keys" => array("title"),
|
||||
"db_table" => "incident",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/ticket.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Ticket Ref", "description"=>"Refence number ofr this incident", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("title", array("label"=>"Title", "description"=>"Overview of the Incident", "allowed_values"=>null, "sql"=>"title", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("type", array("label"=>"Type", "description"=>"Type of the Incident", "allowed_values"=>new ValueSetEnum("Network,Server,Desktop,Application"), "sql"=>"type", "default_value"=>"Server", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("org_id", array("targetclass"=>"bizOrganization", "label"=>"Customer", "description"=>"who is impacted by the ticket", "allowed_values"=>null, "sql"=>"customer", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("customer_name", array("label"=>"Customer", "description"=>"Name of the customer impacted by this ticket", "allowed_values"=>null, "extkey_attcode"=> 'org_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("ticket_status", array("label"=>"Status", "description"=>"Status of the ticket", "allowed_values"=>new ValueSetEnum("New, Assigned, WorkInProgress, Resolved, Closed"), "sql"=>"ticket_status", "default_value"=>"New", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
// SetPossibleValues("status",array("Open","Monitored","Closed"));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("initial_situation", array("label"=>"Initial Situation", "description"=>"Initial situation of the Incident", "allowed_values"=>null, "sql"=>"initial_situation", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("current_situation", array("label"=>"Current Situation", "description"=>"Current situation of the Incident", "allowed_values"=>null, "sql"=>"current_situation", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("start_date", array("label"=>"Starting date", "description"=>"Incident starting date", "allowed_values"=>null, "sql"=>"start_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
// définir une date de défaut à maintenant, alias creation ou modification du ticket
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("last_update", array("label"=>"Last update", "description"=>"last time the Ticket was modified", "allowed_values"=>null, "sql"=>"last_update", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("next_update", array("label"=>"Next update", "description"=>"next time the Ticket is expected to be modified", "allowed_values"=>null, "sql"=>"next_update", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("end_date", array("label"=>"Closure Date", "description"=>"Date when the Ticket was closed", "allowed_values"=>null, "sql"=>"closed_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("caller_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Caller", "description"=>"person that trigger incident", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p WHERE p.org_id = :this->org_id'), "sql"=>"caller_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array("org_id"))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("caller_mail", array("label"=>"Caller", "description"=>"Person that trigger this incident", "allowed_values"=>null, "extkey_attcode"=> 'caller_id', "target_attcode"=>"email")));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Impact", "description"=>"Impact of the Incident", "allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("workgroup_id", array("targetclass"=>"bizWorkgroup", "jointype"=> "", "label"=>"Workgroup", "description"=>"which workgroup is owning ticket", "allowed_values"=>null, "sql"=>"workgroup_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("workgroup_name", array("label"=>"Workgroup", "description"=>"name of workgroup managing the Ticket", "allowed_values"=>null, "extkey_attcode"=> 'workgroup_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("agent_id", array("targetclass"=>"bizPerson", "jointype"=> "", "label"=>"Agent", "description"=>"who is managing the ticket", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p JOIN lnkContactTeam AS l ON l.contact_id=p.id JOIN bizTeam AS t ON l.team_id=t.id JOIN bizWorkgroup AS w ON w.team_id=t.id WHERE w.id = :this->workgroup_id'), "sql"=>"agent_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array('workgroup_id'))));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("agent_mail", array("label"=>"Agent", "description"=>"mail of agent managing the Ticket", "allowed_values"=>null, "extkey_attcode"=> 'agent_id', "target_attcode"=>"email")));
|
||||
// Comment afficher le first + last name de l'agent ? Est-ce utile d'ajouter ce champ?
|
||||
MetaModel::Init_AddAttribute(new AttributeText("action_log", array("label"=>"Action Logs", "description"=>"List all action performed during the incident", "allowed_values"=>null, "sql"=>"action_log", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("severity", array("label"=>"Severity", "description"=>"Field defining the criticity if the incident", "allowed_values"=>new ValueSetEnum("critical,medium,low"), "sql"=>"criticity", "default_value"=>"low", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("assignment_count", array("label"=>"Assignment Count", "description"=>"Number of times this ticket was assigned or reassigned", "allowed_values"=>null, "sql"=>"assignment_count", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("resolution", array("label"=>"Resolution", "description"=>"Description of the resolution", "allowed_values"=>null, "sql"=>"resolution", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("impacted_infra_manual", array("label"=>"Impacted Infrastructure", "description"=>"CIs that are not meeting the SLA", "linked_class"=>"lnkInfraTicket", "ext_key_to_me"=>"ticket_id", "ext_key_to_remote"=>"infra_id", "allowed_values"=>null, "count_min"=>1, "count_max"=>0, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("related_tickets", array("label"=>"Related Tickets", "description"=>"Other incident tickets related to this one", "linked_class"=>"lnkRelatedTicket", "ext_key_to_me"=>"ticket_id", "ext_key_to_remote"=>"rel_ticket_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array(/*'impacted_infra_computed',*/ 'impacted_infra_manual'))));
|
||||
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("title");
|
||||
MetaModel::Init_AddFilterFromAttribute("type");
|
||||
MetaModel::Init_AddFilterFromAttribute("org_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("caller_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("ticket_status");
|
||||
MetaModel::Init_AddFilterFromAttribute("start_date");
|
||||
MetaModel::Init_AddFilterFromAttribute("last_update");
|
||||
MetaModel::Init_AddFilterFromAttribute("end_date");
|
||||
MetaModel::Init_AddFilterFromAttribute("workgroup_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("agent_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("severity");
|
||||
MetaModel::Init_AddFilterFromAttribute("assignment_count");
|
||||
|
||||
// doit-on aussi ajouter un filtre sur les extfields lié à une extkey ? ici le name de l'agent?
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name','title', 'org_id', 'type','ticket_status', 'severity','start_date', 'initial_situation', 'current_situation','caller_id', 'impact', 'last_update', 'next_update','end_date', 'assignment_count', 'workgroup_id','agent_id','action_log','resolution')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'title', 'org_id', 'type','ticket_status','severity','start_date', 'initial_situation')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'title', 'org_id', 'caller_id','type', 'ticket_status', 'severity','start_date', 'last_update','end_date','agent_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'title', 'org_id','caller_id','type','ticket_status', 'severity','start_date', 'last_update', 'end_date','agent_id')); // Criteria of the advanced search form
|
||||
|
||||
// State machine
|
||||
MetaModel::Init_DefineState("New", array("label"=>"New (Unassigned)", "description"=>"Newly created ticket", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, 'assignment_count' => OPT_ATT_HIDDEN, 'end_date' => OPT_ATT_HIDDEN, 'next_update' => OPT_ATT_HIDDEN, 'last_update' => OPT_ATT_HIDDEN,
|
||||
"title"=>OPT_ATT_MANDATORY, "org_id"=>OPT_ATT_MANDATORY, "caller_id"=>OPT_ATT_MANDATORY, "initial_situation"=>OPT_ATT_MANDATORY, "start_date"=>OPT_ATT_MANDATORY, "workgroup_id"=>OPT_ATT_MANDATORY,
|
||||
"severity"=>OPT_ATT_MANDATORY, "agent_id"=>OPT_ATT_HIDDEN,"impacted_infra_manual"=>OPT_ATT_MANDATORY, "related_tickets"=>OPT_ATT_MUSTPROMPT,"resolution"=>OPT_ATT_HIDDEN)));
|
||||
MetaModel::Init_DefineState("Assigned", array("label"=>"Assigned", "description"=>"Ticket is assigned to somebody", "attribute_inherit"=>null,
|
||||
"attribute_list"=>array('name' => OPT_ATT_READONLY, "title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "initial_situation"=>OPT_ATT_READONLY, "start_date"=>OPT_ATT_READONLY,'assignment_count' => OPT_ATT_READONLY,'end_date' => OPT_ATT_HIDDEN, "workgroup_id"=>OPT_ATT_READONLY, "agent_id"=>OPT_ATT_MUSTCHANGE,"resolution"=>OPT_ATT_HIDDEN)));
|
||||
MetaModel::Init_DefineState("WorkInProgress", array("label"=>"Work In Progress", "description"=>"Work is in progress", "attribute_inherit"=>null, "attribute_list"=>array("title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "initial_situation"=>OPT_ATT_READONLY,'end_date' => OPT_ATT_HIDDEN, "start_date"=>OPT_ATT_READONLY,"workgroup_id"=>OPT_ATT_MANDATORY, "agent_id"=>OPT_ATT_MANDATORY,"action_log"=>OPT_ATT_MANDATORY,"impact"=>OPT_ATT_READONLY,"severity"=>OPT_ATT_READONLY)));
|
||||
MetaModel::Init_DefineState("Resolved", array("label"=>"Resolved", "description"=>"Ticket is resolved", "attribute_inherit"=>null, "attribute_list"=>array('name' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY, "title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "initial_situation"=>OPT_ATT_READONLY,"current_situation"=>OPT_ATT_READONLY,'end_date' => OPT_ATT_READONLY,'last_update' => OPT_ATT_READONLY,'next_update' => OPT_ATT_READONLY, "start_date"=>OPT_ATT_READONLY,"workgroup_id"=>OPT_ATT_READONLY, "agent_id"=>OPT_ATT_READONLY,"action_log"=>OPT_ATT_READONLY,"impact"=>OPT_ATT_READONLY,"severity"=>OPT_ATT_READONLY,"resolution"=>OPT_ATT_MUSTCHANGE)));
|
||||
MetaModel::Init_DefineState("Closed", array("label"=>"Closed", "description"=>"Ticket is closed", "attribute_inherit"=>null, "attribute_list"=>array('name' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY, "title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "initial_situation"=>OPT_ATT_READONLY,"current_situation"=>OPT_ATT_READONLY,'end_date' => OPT_ATT_READONLY,'last_update' => OPT_ATT_READONLY,'next_update' => OPT_ATT_READONLY, "start_date"=>OPT_ATT_READONLY,"workgroup_id"=>OPT_ATT_READONLY, "agent_id"=>OPT_ATT_READONLY,"action_log"=>OPT_ATT_READONLY,"impact"=>OPT_ATT_READONLY,"severity"=>OPT_ATT_READONLY,"resolution"=>OPT_ATT_READONLY)));
|
||||
|
||||
MetaModel::Init_DefineStimulus("ev_assign", new StimulusUserAction(array("label"=>"Assign this ticket", "description"=>"Assign this ticket to a group and an agent")));
|
||||
MetaModel::Init_DefineStimulus("ev_reassign", new StimulusUserAction(array("label"=>"Reassign this ticket", "description"=>"Reassign this ticket to a different group and agent")));
|
||||
MetaModel::Init_DefineStimulus("ev_start_working", new StimulusUserAction(array("label"=>"Work on this ticket", "description"=>"Start working on this ticket")));
|
||||
MetaModel::Init_DefineStimulus("ev_resolve", new StimulusUserAction(array("label"=>"Resolve this ticket", "description"=>"Resolve this ticket")));
|
||||
MetaModel::Init_DefineStimulus("ev_close", new StimulusUserAction(array("label"=>"Close this ticket", "description"=>"Close this ticket")));
|
||||
|
||||
MetaModel::Init_DefineTransition("New", "ev_assign", array("target_state"=>"Assigned", "actions"=>array('IncrementAssignmentCount'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Assigned", "ev_reassign", array("target_state"=>"Assigned", "actions"=>array('IncrementAssignmentCount','SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Assigned", "ev_start_working", array("target_state"=>"WorkInProgress", "actions"=>array('SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("WorkInProgress", "ev_reassign", array("target_state"=>"Assigned", "actions"=>array('IncrementAssignmentCount','SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("WorkInProgress", "ev_resolve", array("target_state"=>"Resolved", "actions"=>array('SetLastUpdate'), "user_restriction"=>null));
|
||||
MetaModel::Init_DefineTransition("Resolved", "ev_close", array("target_state"=>"Closed", "actions"=>array('SetClosureDate','SetLastUpdate'), "user_restriction"=>null));
|
||||
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('org_id', $oGenerator->GetOrganizationId());
|
||||
$this->Set('title', $oGenerator->GenerateString("enum(Site,Server,Line)| |enum(is down,is flip-flopping,is not responding)"));
|
||||
$this->Set('agent_id', $oGenerator->GenerateKey("bizPerson", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('ticket_status', $oGenerator->GenerateString("enum(Open,Closed,Closed,Monitored)"));
|
||||
$this->Set('start_date', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
$this->Set('last_update', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
$this->Set('end_date', $oGenerator->GenerateString("2007-|number(07-12)|-|number(01-30)| |number(07-12)|:|number(00-59)|:|number(00-59)"));
|
||||
}
|
||||
|
||||
// State machine actions
|
||||
public function IncrementAssignmentCount($sStimulusCode)
|
||||
{
|
||||
$this->Set('assignment_count', $this->Get('assignment_count') + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function SetClosureDate($sStimulusCode)
|
||||
{
|
||||
$this->Set('end_date', time());
|
||||
return true;
|
||||
}
|
||||
|
||||
public function SetLastUpdate($sStimulusCode)
|
||||
{
|
||||
$this->Set('last_update', time());
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ComputeValues()
|
||||
{
|
||||
$iKey = $this->GetKey();
|
||||
if ($iKey < 0)
|
||||
{
|
||||
// Object not yet in the Database
|
||||
$iKey = MetaModel::GetNextKey(get_class($this));
|
||||
}
|
||||
$sName = sprintf('I-%06d', $iKey);
|
||||
$this->Set('name', $sName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Infra and a Incident
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkRelatedTicket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Related Ticket",
|
||||
"description" => "Ticket related to a ticket",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "impact", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("impact"), // ????
|
||||
"db_table" => "related_ticket",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("rel_ticket_id", array("targetclass"=>"bizIncidentTicket", "jointype"=> '', "label"=>"Related Ticket", "description"=>"The related ticket", "allowed_values"=>null, "sql"=>"rel_ticket_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("rel_ticket_name", array("label"=>"Related ticket", "description"=>"Name of the related ticket", "allowed_values"=>null, "extkey_attcode"=> 'rel_ticket_id', "target_attcode"=>"title")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("ticket_id", array("targetclass"=>"bizIncidentTicket", "jointype"=> '', "label"=>"Ticket", "description"=>"Ticket number", "allowed_values"=>null, "sql"=>"ticket_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("ticket_name", array("label"=>"Ticket Name", "description"=>"Name of the ticket", "allowed_values"=>null, "extkey_attcode"=> 'ticket_id', "target_attcode"=>"title")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Impact", "description"=>"Impact on the related ticket", "allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("rel_ticket_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("ticket_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('rel_ticket_id', 'ticket_id', 'impact')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('rel_ticket_id', 'ticket_id', 'impact')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('rel_ticket_id', 'ticket_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('rel_ticket_id', 'ticket_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('infra_id', $oGenerator->GenerateKey("logInfra", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('ticket_id', $oGenerator->GenerateKey("bizIncidentTicket", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('impact', $oGenerator->GenerateString("enum(none,mandatory,partial)"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Infra and a Incident
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkInfraTicket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Infra Ticket",
|
||||
"description" => "Infra impacted by a ticket",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "impact", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("impact"), // ????
|
||||
"db_table" => "infra_ticket",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("infra_id", array("targetclass"=>"logInfra", "jointype"=> '', "label"=>"Infrastructure", "description"=>"The infrastructure impacted", "allowed_values"=>null, "sql"=>"infra_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("infra_name", array("label"=>"Infrastructure Name", "description"=>"Name of the impacted infrastructure", "allowed_values"=>null, "extkey_attcode"=> 'infra_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("ticket_id", array("targetclass"=>"bizIncidentTicket", "jointype"=> '', "label"=>"Ticket #", "description"=>"Ticket number", "allowed_values"=>null, "sql"=>"ticket_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("ticket_name", array("label"=>"Ticket Name", "description"=>"Name of the ticket", "allowed_values"=>null, "extkey_attcode"=> 'ticket_id', "target_attcode"=>"title")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Impact", "description"=>"Level of impact of the infra by the related ticket", "allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("infra_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("ticket_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('infra_id', 'ticket_id', 'impact')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('infra_id', 'ticket_id', 'impact')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('infra_id', 'ticket_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('infra_id', 'ticket_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('infra_id', $oGenerator->GenerateKey("logInfra", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('ticket_id', $oGenerator->GenerateKey("bizIncidentTicket", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('impact', $oGenerator->GenerateString("enum(none,mandatory,partial)"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* n-n link between any Contqct and a Incident
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class lnkContactTicket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Contact Ticket",
|
||||
"description" => "Contacts to be notify for a ticket",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "link_id",
|
||||
"name_attcode" => "role", // ????
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("role"), // ????
|
||||
"db_table" => "contact_ticket",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("contact_id", array("targetclass"=>"bizContact", "jointype"=> '', "label"=>"Contact", "description"=>"Contact to Notify", "allowed_values"=>null, "sql"=>"contact_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("contact_email", array("label"=>"Contact email", "description"=>"Mail for the contact", "allowed_values"=>null, "extkey_attcode"=> 'contact_id', "target_attcode"=>"email")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("ticket_id", array("targetclass"=>"bizIncidentTicket", "jointype"=> '', "label"=>"Ticket #", "description"=>"Ticket number", "allowed_values"=>null, "sql"=>"ticket_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("ticket_name", array("label"=>"Ticket Name", "description"=>"Name of the ticket", "allowed_values"=>null, "extkey_attcode"=> 'ticket_id', "target_attcode"=>"title")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("role", array("label"=>"Role", "description"=>"Role of the contact", "allowed_values"=>null, "sql"=>"role", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("contact_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("ticket_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('contact_id', 'ticket_id', 'role')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('contact_id', 'ticket_id', 'role')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('contact_id', 'ticket_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('contact_id', 'ticket_id')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function Generate(cmdbDataGenerator $oGenerator)
|
||||
{
|
||||
$this->Set('infra_id', $oGenerator->GenerateKey("logInfra", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('ticket_id', $oGenerator->GenerateKey("bizIncidentTicket", array('org_id' =>$oGenerator->GetOrganizationId() )));
|
||||
$this->Set('impact', $oGenerator->GenerateString("enum(none,mandatory,partial)"));
|
||||
}
|
||||
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//**
|
||||
//* A workgroup is a queue in a given call tracking system
|
||||
//* It belongs to a team and a given organization
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class bizWorkgroup extends logRealObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "bizmodel,searchable",
|
||||
"name" => "Workgroup",
|
||||
"description" => "Call tracking workgroup",
|
||||
"key_type" => "",
|
||||
"key_label" => "id",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array("org_name", "name"), // inherited attributes
|
||||
"db_table" => "workgroups",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "../business/templates/default.html",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("label"=>"Status", "description"=>"Lifecycle status", "allowed_values"=>new ValueSetEnum('production,implementation,obsolete'), "sql"=>"status", "default_value"=>"implementation", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("org_name", array("label"=>"Organization", "description"=>"Company / Department owning this object", "allowed_values"=>null, "extkey_attcode"=> 'org_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("team_id", array("targetclass"=>"bizTeam", "label"=>"Team", "description"=>"Team owning the workgroup", "allowed_values"=>null, "sql"=>"team_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("team_name", array("label"=>"Team Name", "description"=>"name of the team", "allowed_values"=>null, "extkey_attcode"=> 'team_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("role", array("label"=>"Role", "description"=>"Role of this work group", "allowed_values"=>new ValueSetEnum("1st level support,2nd level support,3rd level support"), "sql"=>"role", "default_value"=>"1st level support", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("org_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("team_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("role");
|
||||
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'status', 'org_id', 'team_id', 'role')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'team_id','role')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'status', 'team_id')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('name', 'status', 'team_id','role')); // Criteria of the advanced search form
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
?>
|
||||
1721
business/itop.business.class.inc.php
Normal file
1721
business/itop.business.class.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
30
business/templates/application.html
Normal file
30
business/templates/application.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/software.jpg" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizApplication WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Impacted_Client_Applications">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="server_id" object_id="$pkey$" target_attr="client_id" encoding="text/oql">SELECT lnkClientServer WHERE server_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Application_Server">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="client_id" object_id="$pkey$" target_attr="server_id" encoding="text/oql">SELECT lnkClientServer WHERE client_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Incidents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="ticket_id" encoding="text/sibusql">lnkInfraTicket: infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Changes">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/sibusql">bizChangeTicket: PKEY IS ticket_id IN (lnkInfraChangeTicket: infra_id = $pkey$)</itopblock>
|
||||
</itoptab>
|
||||
|
||||
<itoptab name="Contracts">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="contract_id" encoding="text/oql">SELECT lnkInfraContract WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Groups">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="infra_group_id" encoding="text/oql">SELECT lnkInfraGrouping WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
|
||||
</itoptabs>
|
||||
17
business/templates/change.html
Normal file
17
business/templates/change.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/imageChange.gif" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Impacted_Infrastructures">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="ticket_id" object_id="$pkey$" target_attr="infra_id" encoding="text/oql">SELECT lnkInfraChangeTicket WHERE ticket_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Contacts_to_Notify">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="change_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactChange WHERE change_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
</itoptabs>
|
||||
<br style="clear:both"/>
|
||||
21
business/templates/circuit.html
Normal file
21
business/templates/circuit.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/sibusql" label="Actions">$class$: pkey = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/WanLinks.jpg" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/sibusql">$class$: pkey = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Contacts">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Incidents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="ticket_id" encoding="text/oql">SELECT lnkInfraTicket WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Changes">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT bizChangeTicket AS Change JOIN lnkInfraChangeTicket AS Link ON Link.ticket_id = Change.id WHERE Link.infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="doc_id" encoding="text/oql">SELECT lnkDocumentRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
18
business/templates/contract.html
Normal file
18
business/templates/contract.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/erwanContracts.jpg" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizContract WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Covered_Infrastructures">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="contract_id" object_id="$pkey$" target_attr="infra_id" encoding="text/oql">SELECT lnkInfraContract WHERE contract_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Contacts">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="contract_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactContract WHERE contract_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="contract_id" object_id="$pkey$" target_attr="doc_id" encoding="text/oql">SELECT lnkDocumentContract WHERE contract_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
8
business/templates/default.html
Normal file
8
business/templates/default.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/sibusql" label="Actions">$class$: pkey = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/tar.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/sibusql">$class$: pkey = $pkey$</itopblock>
|
||||
|
||||
7
business/templates/document.html
Normal file
7
business/templates/document.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/sibusql" label="Actions">$class$: pkey = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/folder_documents.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
16
business/templates/group.html
Normal file
16
business/templates/group.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/tar.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizInfraGroup WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Infrastructures">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_group_id" object_id="$pkey$" target_attr="infra_id" encoding="text/oql">SELECT lnkInfraGrouping WHERE infra_group_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Contacts">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
</itoptabs>
|
||||
14
business/templates/interface.html
Normal file
14
business/templates/interface.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/tar.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizInterface WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Groups">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="infra_group_id" encoding="text/oql">SELECT lnkInfraGrouping WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
|
||||
</itoptabs>
|
||||
11
business/templates/knownError.html
Normal file
11
business/templates/knownError.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizKnownError WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Related_Intrastructures">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="error_id" object_id="$pkey$" target_attr="infra_id" encoding="text/oql">SELECT lnkInfraError WHERE error_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
25
business/templates/location.html
Normal file
25
business/templates/location.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/starthere.png" style="margin-top:-20px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizLocation WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Contacts">
|
||||
<itopblock blockclass="DisplayBlock" type="list" object_id="$pkey$" target_attr="location_id" encoding="text/oql">SELECT bizContact WHERE location_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Servers">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="location_id">SELECT bizServer WHERE location_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="PCs">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="location_id">SELECT bizPC WHERE location_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Network_Devices">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="location_id">SELECT bizNetworkDevice WHERE location_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="doc_id" encoding="text/oql">SELECT lnkDocumentRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
28
business/templates/network.device.html
Normal file
28
business/templates/network.device.html
Normal file
@@ -0,0 +1,28 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/connect_to_network.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizNetworkDevice WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Interfaces">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="device_id">SELECT bizInterface WHERE device_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Contacts">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactInfra WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Incidents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="ticket_id" encoding="text/oql">SELECT lnkInfraTicket WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Changes">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/sibusql">bizChangeTicket: PKEY IS ticket_id IN (lnkInfraChangeTicket: infra_id = $pkey$)</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Groups">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="infra_group_id" encoding="text/oql">SELECT lnkInfraGrouping WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="doc_id" encoding="text/oql">SELECT lnkDocumentRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
|
||||
30
business/templates/pc.html
Normal file
30
business/templates/pc.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/laptop_pcmcia.png" style="margin-top:-20px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizPC WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Applications">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="device_id">SELECT bizApplication WHERE device_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Patches">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="device_id">SELECT bizPatch WHERE device_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Interfaces">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="device_id">SELECT bizInterface WHERE device_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Contacts">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Incidents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="ticket_id" encoding="text/oql">SELECT lnkInfraTicket WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Groups">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="infra_group_id" encoding="text/oql">SELECT lnkInfraGrouping WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="doc_id" encoding="text/oql">SELECT lnkDocumentRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
22
business/templates/person.html
Normal file
22
business/templates/person.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/users2-big.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizPerson WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Teams">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="contact_id" object_id="$pkey$" target_attr="team_id" encoding="text/oql">SELECT lnkContactTeam WHERE contact_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Infrastructure">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="contact_id" object_id="$pkey$" target_attr="object_id" encoding="text/oql">SELECT lnkContactRealObject WHERE contact_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Service_Calls">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT bizServiceCall WHERE caller_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="doc_id" encoding="text/oql">SELECT lnkDocumentRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
34
business/templates/server.html
Normal file
34
business/templates/server.html
Normal file
@@ -0,0 +1,34 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/network-server.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizServer WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Applications">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="device_id">SELECT bizApplication WHERE device_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Patches">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="device_id">SELECT bizPatch WHERE device_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Interfaces">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql" object_id="$pkey$" target_attr="device_id">SELECT bizInterface WHERE device_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Contacts">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Incidents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="ticket_id" encoding="text/oql">SELECT lnkInfraTicket WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Changes">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT bizChangeTicket AS Change JOIN lnkInfraChangeTicket AS Link ON Link.ticket_id = Change.id WHERE Link.infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Groups">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="infra_id" object_id="$pkey$" target_attr="infra_group_id" encoding="text/oql">SELECT lnkInfraGrouping WHERE infra_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="doc_id" encoding="text/oql">SELECT lnkDocumentRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
</itoptabs>
|
||||
13
business/templates/service.html
Normal file
13
business/templates/service.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/sibusql" label="Actions">$class$: pkey = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/kservices-big.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT bizService WHERE id=$pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Contracts">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="list" encoding="text/oql" object_id="$pkey$" target_attr="service_id">SELECT bizContract WHERE service_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
|
||||
18
business/templates/serviceCall.html
Normal file
18
business/templates/serviceCall.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/messagebox_warning.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Impacted_Infrastructures">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="call_id" object_id="$pkey$" target_attr="infra_id" encoding="text/oql">SELECT lnkInfraCall WHERE call_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Related_Incidents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="call_id" object_id="$pkey$" target_attr="ticket_id" encoding="text/oql">SELECT lnkCallTicket WHERE call_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
|
||||
</itoptabs>
|
||||
<br style="clear:both"/>
|
||||
12
business/templates/serviceRequest.html
Normal file
12
business/templates/serviceRequest.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/erwanContracts.jpg" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Service_Items">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT bizServiceItem WHERE request_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
13
business/templates/software.html
Normal file
13
business/templates/software.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/sibusql" label="Actions">$class$: pkey = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/software.jpg" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/sibusql">bizSoftware: pkey = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Installed_Instances">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/sibusql">bizApplication: soft_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
</itoptabs>
|
||||
22
business/templates/team.html
Normal file
22
business/templates/team.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/users2-big.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT $class$ WHERE id = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Members">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="team_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactTeam WHERE team_id=$pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Infrastructures">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="contact_id" object_id="$pkey$" target_attr="infra_id" encoding="text/oql">SELECT lnkContactInfra WHERE contact_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Workgroups">
|
||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT bizWorkgroup WHERE team_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
<itoptab name="Documents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="object_id" object_id="$pkey$" target_attr="doc_id" encoding="text/oql">SELECT lnkDocumentRealObject WHERE object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
</itoptabs>
|
||||
24
business/templates/ticket.html
Normal file
24
business/templates/ticket.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/sibusql" label="Actions">$class$: pkey = $pkey$</itopblock>
|
||||
<h1>$class_name$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $pkey$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../images/messagebox_warning.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/sibusql">$class$: pkey = $pkey$</itopblock>
|
||||
<itoptabs>
|
||||
<itoptab name="Impacted_Infrastructures">
|
||||
<itopblock blockclass="DisplayBlock" type="list" link_attr="ticket_id" object_id="$pkey$" target_attr="infra_id" encoding="text/oql">SELECT lnkInfraTicket WHERE ticket_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Related_Incidents">
|
||||
<itopblock blockclass="DisplayBlock" type="links" link_attr="ticket_id" object_id="$pkey$" target_attr="rel_ticket_id" encoding="text/oql">SELECT lnkRelatedTicket WHERE ticket_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Contacts_to_Notify">
|
||||
<itopblock blockclass="DisplayBlock" type="list" link_attr="ticket_id" object_id="$pkey$" target_attr="contact_id" encoding="text/oql">SELECT lnkContactTicket WHERE ticket_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
<itoptab name="Email_Notifications">
|
||||
<itopblock blockclass="DisplayBlock" type="list" parameters="menu:0;" encoding="text/oql">SELECT EventNotificationEmail AS Ev JOIN TriggerOnObject AS T ON Ev.trigger_id = T.id WHERE T.target_class = 'bizIncidentTicket' AND Ev.object_id = $pkey$</itopblock>
|
||||
</itoptab>
|
||||
|
||||
|
||||
</itoptabs>
|
||||
<br style="clear:both"/>
|
||||
272
business/test_farm.class.inc.php
Normal file
272
business/test_farm.class.inc.php
Normal file
@@ -0,0 +1,272 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* test_farm.class.inc.php
|
||||
* User defined objects, for unit testing - SQL generation oriented (complex links)
|
||||
*
|
||||
* @package iTopUnitTests
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Business implementation demo
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//todo MetaModel::RegisterRelation("Potes", array("description"=>"ceux dont l'email ressemble au mien", "verb_down"=>"est pote de", "verb_up"=>"est pote de"));
|
||||
|
||||
|
||||
//todo MetaModel::RegisterZList("list1", array("description"=>"une premiere list, just for fun", "type"=>"attributes"));
|
||||
//todo MetaModel::RegisterZList("list2", array("description"=>"la secunda e meliora", "type"=>"attributes"));
|
||||
//todo MetaModel::RegisterZList("list3", array("description"=>"la variante qui tue", "type"=>"filters"));
|
||||
|
||||
|
||||
class Animal extends cmdbObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Animal",
|
||||
"description" => "An animal",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(""),
|
||||
"db_table" => "animals",
|
||||
"db_key_field" => "animalid",
|
||||
"db_finalclass_field" => "actualclass",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("sex", array("label"=>"sex", "description"=>"sex", "allowed_values"=>new ValueSetEnum('male, female'), "sql"=>"sex", "default_value"=>"male", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("species", array("label"=>"species", "description"=>"species", "allowed_values"=>null, "sql"=>"species", "default_value"=>"xxx", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("speed", array("label"=>"walk speed", "description"=>"maximum possible speed m.s-1", "allowed_values"=>null, "sql"=>"speed", "default_value"=>4, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("mother", array("label"=>"mother", "description"=>"mother", "allowed_values"=>null, "sql"=>"mother", "targetclass"=>"Animal", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("father", array("label"=>"father", "description"=>"father", "allowed_values"=>null, "sql"=>"father", "targetclass"=>"Animal", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("sex");
|
||||
MetaModel::Init_AddFilterFromAttribute("species");
|
||||
MetaModel::Init_AddFilterFromAttribute("speed");
|
||||
MetaModel::Init_AddFilterFromAttribute("mother");
|
||||
MetaModel::Init_AddFilterFromAttribute("father");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Mammal extends Animal
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Mammal",
|
||||
"description" => "An animal with some characteristics",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "mammals",
|
||||
"db_key_field" => "mammalid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"name", "description"=>"name", "allowed_values"=>null, "sql"=>"name", "default_value"=>"xxx", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("height", array("label"=>"height", "description"=>"size in centimeters", "allowed_values"=>null, "sql"=>"height", "default_value"=>1, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("birth", array("label"=>"birth date", "description"=>"birth date", "allowed_values"=>null, "sql"=>"birth", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("member", array("label"=>"member", "description"=>"leader", "allowed_values"=>null, "sql"=>"member", "targetclass"=>"Group", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
|
||||
// ? MetaModel::Init_AddAttribute(new AttributeLinkedSet("a2a", array("label"=>"animal to animal", "description"=>"interanimal relations", "depends_on"=>array(), "linked_class"=>"Animal2animal", "ext_key_to_me"=>"animal1", "count_min"=>0, "count_max"=>10, "allowed_values"=>null)));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("height");
|
||||
MetaModel::Init_AddFilterFromAttribute("birth");
|
||||
MetaModel::Init_AddFilterFromAttribute("member");
|
||||
}
|
||||
}
|
||||
|
||||
class Bird extends Animal
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Bird",
|
||||
"description" => "Un regroupement de gens",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "birds",
|
||||
"db_key_field" => "birdid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_OverloadAttributeParams("species", array("allowed_values"=>array('geese', 'rooster', 'chicken', 'turckey', 'pie', 'corbeau')));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
}
|
||||
}
|
||||
|
||||
class WalkingBird extends Bird
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "WalkingBird",
|
||||
"description" => "A bird which nevers flies",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "walkingbirds",
|
||||
"db_key_field" => "walkingbirdid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_OverloadAttributeParams("species", array("allowed_values"=>array('geese', 'rooster', 'chicken', 'turckey')));
|
||||
MetaModel::Init_InheritFilters();
|
||||
}
|
||||
}
|
||||
|
||||
class FlyingBird extends Bird
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "FlyingBird",
|
||||
"description" => "A bird which nevers flies",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "flyingbirds",
|
||||
"db_key_field" => "flyingbirdid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_OverloadAttributeParams("species", array("allowed_values"=>array('pie', 'corbeau')));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("flyingspeed", array("label"=>"flying speed", "description"=>"flying at ms.s-1", "allowed_values"=>null, "sql"=>"headcount", "default_value"=>10, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("flyingspeed");
|
||||
}
|
||||
}
|
||||
|
||||
class AnimalRelation extends cmdbObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "AnimalRelation",
|
||||
"description" => "Link between two animals",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "a2a",
|
||||
"db_key_field" => "linkid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
|
||||
// What makes it being a link...
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("animal1", array("label"=>"source", "description"=>"the animal which does ...", "allowed_values"=>null, "sql"=>"a1", "targetclass"=>"Animal", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("animal2", array("label"=>"target", "description"=>"the animal to which something is done...", "allowed_values"=>null, "sql"=>"a2", "targetclass"=>"Animal", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("animal1");
|
||||
MetaModel::Init_AddFilterFromAttribute("animal2");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class EaterToEaten extends AnimalRelation
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "EaterToEaten",
|
||||
"description" => "Animal 1 eats animal 2",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "eatertoeaten",
|
||||
"db_key_field" => "eatertoeatonid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("DeadOrAlive", array("label"=>"DeadOrAlive", "description"=>"State in which it is ok for the eater to proceed", "allowed_values"=>new ValueSetEnum('dead, fresh, cooked'), "sql"=>"deadoralive", "default_value"=>"fresh", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("DeadOrAlive");
|
||||
}
|
||||
}
|
||||
|
||||
class Group extends cmdbObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "blah",
|
||||
"name" => "Group",
|
||||
"description" => "Group of animals",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "groups",
|
||||
"db_key_field" => "groupid",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"name", "description"=>"name", "allowed_values"=>null, "sql"=>"name", "default_value"=>"xxx", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("leader", array("label"=>"leader", "description"=>"leader", "allowed_values"=>null, "sql"=>"leader", "targetclass"=>"Mammal", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("leader_name", array("label"=>"Leader Name", "description"=>"Name of the leader (defined on Mammal)", "allowed_values"=>null, "extkey_attcode"=> 'leader', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("leader_speed", array("label"=>"Leader Name", "description"=>"Speed of the leader (defined on Animal)", "allowed_values"=>null, "extkey_attcode"=> 'leader', "target_attcode"=>"speed")));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("leader");
|
||||
MetaModel::Init_AddFilterFromAttribute("leader_name");
|
||||
MetaModel::Init_AddFilterFromAttribute("leader_speed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
38
config-dist.php
Normal file
38
config-dist.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
// phpMyORM configuration file
|
||||
//
|
||||
// To be manually edited (or generated by the configuration wizard)
|
||||
//
|
||||
// The file is used in MetaModel::LoadConfig() which does all the necessary initialization job
|
||||
//
|
||||
|
||||
$MySettings = array(
|
||||
'db_host' => 'localhost',
|
||||
'db_user' => 'itop',
|
||||
'db_pwd' => '1T0p',
|
||||
'db_name' => 'itopv06',
|
||||
'db_subname' => '', // use it to differentiate two applications instances running on the same DB
|
||||
);
|
||||
|
||||
// Modules: file names should be specified as a absolute paths
|
||||
|
||||
$MyModules = array(
|
||||
'application' => array (
|
||||
'../application/menunode.class.inc.php',
|
||||
'../application/audit.rule.class.inc.php',
|
||||
// to be continued...
|
||||
),
|
||||
'business' => array (
|
||||
'../business/itop.business.class.inc.php'
|
||||
// to be continued...
|
||||
),
|
||||
'addons' => array (
|
||||
'user rights' => '../addons/userrights/userrightsprofile.class.inc.php',
|
||||
// other modules to come later
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
?>
|
||||
35
config-test-farm.php
Normal file
35
config-test-farm.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
// phpMyORM configuration file
|
||||
//
|
||||
// To be manually edited (or generated by the configuration wizard)
|
||||
//
|
||||
// The file is used in MetaModel::LoadConfig() which does all the necessary initialization job
|
||||
//
|
||||
|
||||
$MySettings = array(
|
||||
'db_host' => 'localhost',
|
||||
'db_user' => 'RomainDBLogin',
|
||||
'db_pwd' => '',
|
||||
'db_name' => 'TestFarm',
|
||||
'db_subname' => '', // use it to differentiate two applications instances running on the same DB
|
||||
);
|
||||
|
||||
// Modules: file names should be specified as a absolute paths
|
||||
|
||||
$MyModules = array(
|
||||
'application' => array (
|
||||
// to be continued...
|
||||
),
|
||||
'business' => array (
|
||||
'../business/test_farm.class.inc.php',
|
||||
// to be continued...
|
||||
),
|
||||
'addons' => array (
|
||||
//'user rights' => '/addons/userrights/userrightsnull.class.inc.php', // or userrightsmatrix.class.inc.php
|
||||
// other modules to come later
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
36
config-test-mymodel.php
Normal file
36
config-test-mymodel.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
// phpMyORM configuration file
|
||||
//
|
||||
// To be manually edited (or generated by the configuration wizard)
|
||||
//
|
||||
// The file is used in MetaModel::LoadConfig() which does all the necessary initialization job
|
||||
//
|
||||
|
||||
|
||||
$MySettings = array(
|
||||
'db_host' => 'localhost',
|
||||
'db_user' => 'itop',
|
||||
'db_pwd' => '1T0p',
|
||||
'db_name' => 'TestBizModelGenericItop',
|
||||
'db_subname' => 'tribute2itop', // use it to differentiate two applications instances running on the same DB
|
||||
);
|
||||
|
||||
// Modules: file names should be specified as a absolute paths
|
||||
|
||||
$MyModules = array(
|
||||
'application' => array (
|
||||
// to be continued...
|
||||
),
|
||||
'business' => array (
|
||||
'../business/business_test.class.inc.php'
|
||||
// to be continued...
|
||||
),
|
||||
'addons' => array (
|
||||
// other modules to come later
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
?>
|
||||
483
core/MyHelpers.class.inc.php
Normal file
483
core/MyHelpers.class.inc.php
Normal file
@@ -0,0 +1,483 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* MyHelpers
|
||||
* various dev/debug helpers, to cleanup or at least re-organize
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
class MyHelpers
|
||||
{
|
||||
public static function CheckValueInArray($sDescription, $value, $aData)
|
||||
{
|
||||
if (!in_array($value, $aData))
|
||||
{
|
||||
self::HandleWrongValue($sDescription, $value, $aData);
|
||||
}
|
||||
}
|
||||
|
||||
public static function CheckKeyInArray($sDescription, $key, $aData)
|
||||
{
|
||||
if (!array_key_exists($key, $aData))
|
||||
{
|
||||
self::HandleWrongValue($sDescription, $key, array_keys($aData));
|
||||
}
|
||||
}
|
||||
|
||||
public static function HandleWrongValue($sDescription, $value, $aData)
|
||||
{
|
||||
if (count($aData) == 0)
|
||||
{
|
||||
$sArrayDesc = "{}";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sArrayDesc = "{".implode(", ", $aData)."}";
|
||||
}
|
||||
// exit!
|
||||
throw new CoreException("Wrong value for $sDescription, found '$value' while expecting a value in $sArrayDesc");
|
||||
}
|
||||
|
||||
// getmicrotime()
|
||||
// format sss.mmmuuupppnnn
|
||||
public static function getmicrotime()
|
||||
{
|
||||
list($usec, $sec) = explode(" ",microtime());
|
||||
return ((float)$usec + (float)$sec);
|
||||
}
|
||||
|
||||
/*
|
||||
* MakeSQLComment
|
||||
* converts hash into text comment which we can use in a (mySQL) query
|
||||
*/
|
||||
public static function MakeSQLComment ($aHash)
|
||||
{
|
||||
if (empty($aHash)) return "";
|
||||
$sComment = "";
|
||||
{
|
||||
foreach($aHash as $sKey=>$sValue)
|
||||
{
|
||||
$sComment .= "\n-- ". $sKey ."=>" . $sValue;
|
||||
}
|
||||
}
|
||||
return $sComment;
|
||||
}
|
||||
|
||||
public static function var_dump_html($aWords, $bFullDisplay = false)
|
||||
{
|
||||
echo "<pre>\n";
|
||||
if ($bFullDisplay)
|
||||
{
|
||||
print_r($aWords); // full dump!
|
||||
}
|
||||
else
|
||||
{
|
||||
var_dump($aWords); // truncate things when they are too big
|
||||
}
|
||||
echo "\n</pre>\n";
|
||||
}
|
||||
|
||||
public static function arg_dump_html()
|
||||
{
|
||||
echo "<pre>\n";
|
||||
echo "GET:\n";
|
||||
var_dump($_GET);
|
||||
echo "POST:\n";
|
||||
var_dump($_POST);
|
||||
echo "\n</pre>\n";
|
||||
}
|
||||
|
||||
public static function var_dump_string($var)
|
||||
{
|
||||
ob_start();
|
||||
print_r($var);
|
||||
$sRet = ob_get_clean();
|
||||
return $sRet;
|
||||
}
|
||||
|
||||
protected static function first_diff_line($s1, $s2)
|
||||
{
|
||||
$aLines1 = explode("\n", $s1);
|
||||
$aLines2 = explode("\n", $s2);
|
||||
for ($i = 0 ; $i < min(count($aLines1), count($aLines2)) ; $i++)
|
||||
{
|
||||
if ($aLines1[$i] != $aLines2[$i]) return $i;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static function highlight_line($sMultiline, $iLine, $sHighlightStart = '<b>', $sHightlightEnd = '</b>')
|
||||
{
|
||||
$aLines = explode("\n", $sMultiline);
|
||||
$aLines[$iLine] = $sHighlightStart.$aLines[$iLine].$sHightlightEnd;
|
||||
return implode("\n", $aLines);
|
||||
}
|
||||
|
||||
protected static function first_diff($s1, $s2)
|
||||
{
|
||||
// do not work fine with multiline strings
|
||||
$iLen1 = strlen($s1);
|
||||
$iLen2 = strlen($s2);
|
||||
for ($i = 0 ; $i < min($iLen1, $iLen2) ; $i++)
|
||||
{
|
||||
if ($s1[$i] !== $s2[$i]) return $i;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static function last_diff($s1, $s2)
|
||||
{
|
||||
// do not work fine with multiline strings
|
||||
$iLen1 = strlen($s1);
|
||||
$iLen2 = strlen($s2);
|
||||
for ($i = 0 ; $i < min(strlen($s1), strlen($s2)) ; $i++)
|
||||
{
|
||||
if ($s1[$iLen1 - $i - 1] !== $s2[$iLen2 - $i - 1]) return array($iLen1 - $i, $iLen2 - $i);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static function text_cmp_html($sText1, $sText2, $sHighlight)
|
||||
{
|
||||
$iDiffPos = self::first_diff_line($sText1, $sText2);
|
||||
$sDisp1 = self::highlight_line($sText1, $iDiffPos, '<div style="'.$sHighlight.'">', '</div>');
|
||||
$sDisp2 = self::highlight_line($sText2, $iDiffPos, '<div style="'.$sHighlight.'">', '</div>');
|
||||
echo "<table style=\"valign=top;\">\n";
|
||||
echo "<tr>\n";
|
||||
echo "<td><pre>$sDisp1</pre></td>\n";
|
||||
echo "<td><pre>$sDisp2</pre></td>\n";
|
||||
echo "</tr>\n";
|
||||
echo "</table>\n";
|
||||
}
|
||||
|
||||
protected static function string_cmp_html($s1, $s2, $sHighlight)
|
||||
{
|
||||
$iDiffPos = self::first_diff($s1, $s2);
|
||||
if ($iDiffPos === false)
|
||||
{
|
||||
echo "strings are identical";
|
||||
return;
|
||||
}
|
||||
$sStart = substr($s1, 0, $iDiffPos);
|
||||
|
||||
$aLastDiff = self::last_diff($s1, $s2);
|
||||
$sEnd = substr($s1, $aLastDiff[0]);
|
||||
|
||||
$sMiddle1 = substr($s1, $iDiffPos, $aLastDiff[0] - $iDiffPos);
|
||||
$sMiddle2 = substr($s2, $iDiffPos, $aLastDiff[1] - $iDiffPos);
|
||||
|
||||
echo "<p>$sStart<span style=\"$sHighlight\">$sMiddle1</span>$sEnd</p>\n";
|
||||
echo "<p>$sStart<span style=\"$sHighlight\">$sMiddle2</span>$sEnd</p>\n";
|
||||
}
|
||||
|
||||
protected static function object_cmp_html($oObj1, $oObj2, $sHighlight)
|
||||
{
|
||||
$sObj1 = self::var_dump_string($oObj1);
|
||||
$sObj2 = self::var_dump_string($oObj2);
|
||||
return self::text_cmp_html($sObj1, $sObj2, $sHighlight);
|
||||
}
|
||||
|
||||
public static function var_cmp_html($var1, $var2, $sHighlight = 'color:red; font-weight:bold;')
|
||||
{
|
||||
if (is_object($var1))
|
||||
{
|
||||
return self::object_cmp_html($var1, $var2, $sHighlight);
|
||||
}
|
||||
else if (count(explode("\n", $var1)) > 1)
|
||||
{
|
||||
// multiline string
|
||||
return self::text_cmp_html($var1, $var2, $sHighlight);
|
||||
}
|
||||
else
|
||||
{
|
||||
return self::string_cmp_html($var1, $var2, $sHighlight);
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_callstack_html($iLevelsToIgnore = 0, $aCallStack = null)
|
||||
{
|
||||
if ($aCallStack == null) $aCallStack = debug_backtrace();
|
||||
|
||||
$aCallStack = array_slice($aCallStack, $iLevelsToIgnore);
|
||||
|
||||
$aDigestCallStack = array();
|
||||
$bFirstLine = true;
|
||||
foreach ($aCallStack as $aCallInfo)
|
||||
{
|
||||
$sLine = empty($aCallInfo['line']) ? "" : $aCallInfo['line'];
|
||||
$sFile = empty($aCallInfo['file']) ? "" : $aCallInfo['file'];
|
||||
$sClass = empty($aCallInfo['class']) ? "" : $aCallInfo['class'];
|
||||
$sType = empty($aCallInfo['type']) ? "" : $aCallInfo['type'];
|
||||
$sFunction = empty($aCallInfo['function']) ? "" : $aCallInfo['function'];
|
||||
|
||||
if ($bFirstLine)
|
||||
{
|
||||
$bFirstLine = false;
|
||||
// For this line do not display the "function name" because
|
||||
// that will be the name of our error handler for sure !
|
||||
$sFunctionInfo = "N/A";
|
||||
}
|
||||
else
|
||||
{
|
||||
$args = '';
|
||||
if (empty($aCallInfo['args'])) $aCallInfo['args'] = array();
|
||||
foreach ($aCallInfo['args'] as $a)
|
||||
{
|
||||
if (!empty($args))
|
||||
{
|
||||
$args .= ', ';
|
||||
}
|
||||
switch (gettype($a))
|
||||
{
|
||||
case 'integer':
|
||||
case 'double':
|
||||
$args .= $a;
|
||||
break;
|
||||
case 'string':
|
||||
$a = Str::pure2html(self::beautifulstr($a, 1024, true, true));
|
||||
$args .= "\"$a\"";
|
||||
break;
|
||||
case 'array':
|
||||
$args .= 'Array('.count($a).')';
|
||||
break;
|
||||
case 'object':
|
||||
$args .= 'Object('.get_class($a).')';
|
||||
break;
|
||||
case 'resource':
|
||||
$args .= 'Resource('.strstr($a, '#').')';
|
||||
break;
|
||||
case 'boolean':
|
||||
$args .= $a ? 'True' : 'False';
|
||||
break;
|
||||
case 'NULL':
|
||||
$args .= 'Null';
|
||||
break;
|
||||
default:
|
||||
$args .= 'Unknown';
|
||||
}
|
||||
}
|
||||
$sFunctionInfo = "$sClass $sType $sFunction($args)";
|
||||
}
|
||||
$aDigestCallStack[] = array('File'=>$sFile, 'Line'=>$sLine, 'Function'=>$sFunctionInfo);
|
||||
}
|
||||
return self::make_table_from_assoc_array($aDigestCallStack);
|
||||
}
|
||||
|
||||
public static function dump_callstack($iLevelsToIgnore = 0, $aCallStack = null)
|
||||
{
|
||||
return self::get_callstack_html($iLevelsToIgnore, $aCallStack);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Source: New
|
||||
// Last modif: 2004/12/20 RQU
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
public static function make_table_from_assoc_array(&$aData)
|
||||
{
|
||||
if (!is_array($aData)) throw new CoreException("make_table_from_assoc_array: Error - the passed argument is not an array");
|
||||
$aFirstRow = reset($aData);
|
||||
if (count($aData) == 0) return '';
|
||||
if (!is_array($aFirstRow)) throw new CoreException("make_table_from_assoc_array: Error - the passed argument is not a bi-dimensional array");
|
||||
$sOutput = "";
|
||||
$sOutput .= "<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"1\">\n";
|
||||
|
||||
// Table header
|
||||
//
|
||||
$sOutput .= " <TR CLASS=celltitle>\n";
|
||||
foreach ($aFirstRow as $fieldname=>$trash) {
|
||||
$sOutput .= " <TD><B>".$fieldname."</B></TD>\n";
|
||||
}
|
||||
$sOutput .= " </TR>\n";
|
||||
|
||||
// Table contents
|
||||
//
|
||||
$iCount = 0;
|
||||
foreach ($aData as $aRow) {
|
||||
$sStyle = ($iCount++ % 2 ? "STYLE=\"background-color : #eeeeee\"" : "");
|
||||
$sOutput .= " <TR $sStyle CLASS=cell>\n";
|
||||
foreach ($aRow as $data) {
|
||||
if (strlen($data) == 0) {
|
||||
$data = " ";
|
||||
}
|
||||
$sOutput .= " <TD>".$data."</TD>\n";
|
||||
}
|
||||
$sOutput .= " </TR>\n";
|
||||
}
|
||||
|
||||
$sOutput .= "</TABLE>\n";
|
||||
return $sOutput;
|
||||
}
|
||||
|
||||
public static function debug_breakpoint($arg)
|
||||
{
|
||||
echo "<H1> Debug breakpoint </H1>\n";
|
||||
MyHelpers::var_dump_html($arg);
|
||||
MyHelpers::dump_callstack();
|
||||
exit;
|
||||
}
|
||||
public static function debug_breakpoint_notempty($arg)
|
||||
{
|
||||
if (empty($arg)) return;
|
||||
echo "<H1> Debug breakpoint (triggered on non-empty value) </H1>\n";
|
||||
MyHelpers::var_dump_html($arg);
|
||||
MyHelpers::dump_callstack();
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlentities()
|
||||
* ... same as htmlentities, but designed for xml !
|
||||
*/
|
||||
public static function xmlentities($string)
|
||||
{
|
||||
return str_replace( array( '&', '"', "'", '<', '>' ), array ( '&' , '"', ''' , '<' , '>' ), $string );
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlencode()
|
||||
* Encodes a string so that for sure it can be output as an xml data string
|
||||
*/
|
||||
public static function xmlencode($string)
|
||||
{
|
||||
return xmlentities(iconv("UTF-8", "UTF-8//IGNORE",$string));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Source: New - format strings for output
|
||||
// Last modif: 2005/01/18 RQU
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
public static function beautifulstr($sLongString, $iMaxLen, $bShowLen=false, $bShowTooltip=true)
|
||||
{
|
||||
if (!is_string($sLongString)) throw new CoreException("beautifulstr: expect a string as 1st argument");
|
||||
|
||||
// Nothing to do if the string is short
|
||||
if (strlen($sLongString) <= $iMaxLen) return $sLongString;
|
||||
|
||||
// Truncate the string
|
||||
$sSuffix = "...";
|
||||
if ($bShowLen) {
|
||||
$sSuffix .= "(".strlen($sLongString)." chars)...";
|
||||
}
|
||||
$sOutput = substr($sLongString, 0, $iMaxLen - strlen($sSuffix)).$sSuffix;
|
||||
$sOutput = htmlspecialchars($sOutput);
|
||||
|
||||
// Add tooltip if required
|
||||
//if ($bShowTooltip) {
|
||||
// $oTooltip = new gui_tooltip($sLongString);
|
||||
// $sOutput = "<SPAN ".$oTooltip->get_mouseOver_code().">".$sOutput."</SPAN>";
|
||||
//}
|
||||
return $sOutput;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Utility class: static methods for cleaning & escaping untrusted (i.e.
|
||||
user-supplied) strings.
|
||||
Any string can (usually) be thought of as being in one of these 'modes':
|
||||
pure = what the user actually typed / what you want to see on the page /
|
||||
what is actually stored in the DB
|
||||
gpc = incoming GET, POST or COOKIE data
|
||||
sql = escaped for passing safely to RDBMS via SQL (also, data from DB
|
||||
queries and file reads if you have magic_quotes_runtime on--which
|
||||
is rare)
|
||||
html = safe for html display (htmlentities applied)
|
||||
Always knowing what mode your string is in--using these methods to
|
||||
convert between modes--will prevent SQL injection and cross-site scripting.
|
||||
This class refers to its own namespace (so it can work in PHP 4--there is no
|
||||
self keyword until PHP 5). Do not change the name of the class w/o changing
|
||||
all the internal references.
|
||||
Example usage: a POST value that you want to query with:
|
||||
$username = Str::gpc2sql($_POST['username']);
|
||||
*/
|
||||
//This sets SQL escaping to use slashes; for Sybase(/MSSQL)-style escaping
|
||||
// ( ' --> '' ), set to true.
|
||||
define('STR_SYBASE', false);
|
||||
class Str
|
||||
{
|
||||
public static function gpc2sql($gpc, $maxLength = false)
|
||||
{
|
||||
return self::pure2sql(self::gpc2pure($gpc), $maxLength);
|
||||
}
|
||||
public static function gpc2html($gpc, $maxLength = false)
|
||||
{
|
||||
return self::pure2html(self::gpc2pure($gpc), $maxLength);
|
||||
}
|
||||
public static function gpc2pure($gpc)
|
||||
{
|
||||
if (ini_get('magic_quotes_sybase')) $pure = str_replace("''", "'", $gpc);
|
||||
else $pure = get_magic_quotes_gpc() ? stripslashes($gpc) : $gpc;
|
||||
return $pure;
|
||||
}
|
||||
public static function html2pure($html)
|
||||
{
|
||||
return html_entity_decode($html);
|
||||
}
|
||||
public static function html2sql($html, $maxLength = false)
|
||||
{
|
||||
return self::pure2sql(self::html2pure($html), $maxLength);
|
||||
}
|
||||
public static function pure2html($pure, $maxLength = false)
|
||||
{
|
||||
// Check for HTML entities, but be careful the DB is in UTF-8
|
||||
return $maxLength
|
||||
? htmlentities(substr($pure, 0, $maxLength), ENT_COMPAT, 'UTF-8')
|
||||
: htmlentities($pure, ENT_COMPAT, 'UTF-8');
|
||||
}
|
||||
public static function pure2sql($pure, $maxLength = false)
|
||||
{
|
||||
if ($maxLength) $pure = substr($pure, 0, $maxLength);
|
||||
return (STR_SYBASE)
|
||||
? str_replace("'", "''", $pure)
|
||||
: addslashes($pure);
|
||||
}
|
||||
public static function sql2html($sql, $maxLength = false)
|
||||
{
|
||||
$pure = self::sql2pure($sql);
|
||||
if ($maxLength) $pure = substr($pure, 0, $maxLength);
|
||||
return self::pure2html($pure);
|
||||
}
|
||||
public static function sql2pure($sql)
|
||||
{
|
||||
return (STR_SYBASE)
|
||||
? str_replace("''", "'", $sql)
|
||||
: stripslashes($sql);
|
||||
}
|
||||
|
||||
public static function xml2pure($xml)
|
||||
{
|
||||
// #@# - not implemented
|
||||
return $xml;
|
||||
}
|
||||
public static function pure2xml($pure)
|
||||
{
|
||||
return self::xmlencode($pure);
|
||||
}
|
||||
|
||||
protected static function xmlentities($string)
|
||||
{
|
||||
return str_replace( array( '&', '"', "'", '<', '>' ), array ( '&' , '"', ''' , '<' , '>' ), $string );
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlencode()
|
||||
* Encodes a string so that for sure it can be output as an xml data string
|
||||
*/
|
||||
protected static function xmlencode($string)
|
||||
{
|
||||
return self::xmlentities(iconv("ISO-8859-1", "UTF-8//IGNORE",$string));
|
||||
}
|
||||
|
||||
public static function islowcase($sString)
|
||||
{
|
||||
return (strtolower($sString) == $sString);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
349
core/action.class.inc.php
Normal file
349
core/action.class.inc.php
Normal file
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
|
||||
require_once('../core/email.class.inc.php');
|
||||
|
||||
/**
|
||||
* A user defined action, to customize the application
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
abstract class Action extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "action",
|
||||
"description" => "Custom action",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_action",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "realclass",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"Name", "description"=>"label", "allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("label"=>"Description", "description"=>"one line description", "allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("label"=>"Status", "description"=>"In production or ?", "allowed_values"=>new ValueSetEnum(array('test'=>'Being tested' ,'enabled'=>'In production', 'disabled'=>'Inactive')), "sql"=>"status", "default_value"=>"test", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("related_triggers", array("label"=>"Related Triggers", "description"=>"Triggers linked to this action", "linked_class"=>"lnkTriggerAction", "ext_key_to_me"=>"action_id", "ext_key_to_remote"=>"trigger_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("name");
|
||||
MetaModel::Init_AddFilterFromAttribute("description");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
abstract public function DoExecute($oTrigger, $aContextArgs);
|
||||
|
||||
public function IsActive()
|
||||
{
|
||||
switch($this->Get('status'))
|
||||
{
|
||||
case 'enabled':
|
||||
case 'test':
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function IsBeingTested()
|
||||
{
|
||||
switch($this->Get('status'))
|
||||
{
|
||||
case 'test':
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A notification
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
abstract class ActionNotification extends Action
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "notification",
|
||||
"description" => "Notification (abstract)",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_action_notification",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'name', 'description', 'status')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An email notification
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class ActionEmail extends ActionNotification
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "email notification",
|
||||
"description" => "Action: Email notification",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "name",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_action_email",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeEmailAddress("test_recipient", array("label"=>"Test recipient", "description"=>"Detination in case status is set to \"Test\"", "allowed_values"=>null, "sql"=>"test_recipient", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("from", array("label"=>"From", "description"=>"Will be sent into the email header", "allowed_values"=>null, "sql"=>"from", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("reply_to", array("label"=>"Reply to", "description"=>"Will be sent into the email header", "allowed_values"=>null, "sql"=>"reply_to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("to", array("label"=>"To", "description"=>"Destination of the email", "allowed_values"=>null, "sql"=>"to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("cc", array("label"=>"Cc", "description"=>"Carbon Copy", "allowed_values"=>null, "sql"=>"cc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("bcc", array("label"=>"bcc", "description"=>"Blind Carbon Copy", "allowed_values"=>null, "sql"=>"bcc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeTemplateString("subject", array("label"=>"subject", "description"=>"Title of the email", "allowed_values"=>null, "sql"=>"subject", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeTemplateText("body", array("label"=>"body", "description"=>"Contents of the email", "allowed_values"=>null, "sql"=>"body", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("importance", array("label"=>"importance", "description"=>"Importance flag", "allowed_values"=>new ValueSetEnum('low,normal,high'), "sql"=>"importance", "default_value"=>'normal', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'test_recipient', 'from', 'reply_to', 'to', 'cc', 'bcc', 'subject', 'body', 'importance')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('name', 'status', 'to', 'subject')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
// count the recipients found
|
||||
protected $m_iRecipients;
|
||||
|
||||
// Errors management : not that simple because we need that function to be
|
||||
// executed in the background, while making sure that any issue would be reported clearly
|
||||
protected $m_aMailErrors; //array of strings explaining the issue
|
||||
|
||||
// returns a the list of emails as a string, or a detailed error description
|
||||
protected function FindRecipients($sRecipAttCode, $aArgs)
|
||||
{
|
||||
$sOQL = $this->Get($sRecipAttCode);
|
||||
if (strlen($sOQL) == '') return '';
|
||||
|
||||
try
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL($sOQL);
|
||||
}
|
||||
catch (OqlException $e)
|
||||
{
|
||||
$this->m_aMailErrors[] = "query syntax error for recipient '$sRecipAttCode'";
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$sClass = $oSearch->GetClass();
|
||||
// Determine the email attribute (the first one will be our choice)
|
||||
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
|
||||
{
|
||||
if ($oAttDef instanceof AttributeEmailAddress)
|
||||
{
|
||||
$sEmailAttCode = $sAttCode;
|
||||
// we've got one, exit the loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isset($sEmailAttCode))
|
||||
{
|
||||
$this->m_aMailErrors[] = "wrong target for recipient '$sRecipAttCode'";
|
||||
return "The objects of the class '$sClass' do not have any email attribute";
|
||||
}
|
||||
|
||||
$oSet = new DBObjectSet($oSearch, array() /* order */, $aArgs);
|
||||
$aRecipients = array();
|
||||
while ($oObj = $oSet->Fetch())
|
||||
{
|
||||
$aRecipients[] = $oObj->Get($sEmailAttCode);
|
||||
$this->m_iRecipients++;
|
||||
}
|
||||
return implode(', ', $aRecipients);
|
||||
}
|
||||
|
||||
|
||||
public function DoExecute($oTrigger, $aContextArgs)
|
||||
{
|
||||
$this->m_iRecipients = 0;
|
||||
$this->m_aMailErrors = array();
|
||||
$bRes = false; // until we do succeed in sending the email
|
||||
try
|
||||
{
|
||||
// Determine recicipients
|
||||
//
|
||||
$sTo = $this->FindRecipients('to', $aContextArgs);
|
||||
$sCC = $this->FindRecipients('cc', $aContextArgs);
|
||||
$sBCC = $this->FindRecipients('bcc', $aContextArgs);
|
||||
|
||||
$sFrom = $this->Get('from');
|
||||
$sReplyTo = $this->Get('reply_to');
|
||||
|
||||
$sSubject = MetaModel::ApplyParams($this->Get('subject'), $aContextArgs);
|
||||
$sBody = MetaModel::ApplyParams($this->Get('body'), $aContextArgs);
|
||||
|
||||
$oEmail = new Email();
|
||||
|
||||
if ($this->IsBeingTested())
|
||||
{
|
||||
$oEmail->SetSubject('TEST['.$sSubject.']');
|
||||
$sTestBody = $sBody;
|
||||
$sTestBody .= "<div style=\"border: dashed;\">\n";
|
||||
$sTestBody .= "<h1>Testing email notification ".$this->GetHyperlink()."</h1>\n";
|
||||
$sTestBody .= "<p>The email should be sent with the following properties\n";
|
||||
$sTestBody .= "<ul>\n";
|
||||
$sTestBody .= "<li>TO: $sTo</li>\n";
|
||||
$sTestBody .= "<li>CC: $sCC</li>\n";
|
||||
$sTestBody .= "<li>BCC: $sBCC</li>\n";
|
||||
$sTestBody .= "<li>From: $sFrom</li>\n";
|
||||
$sTestBody .= "<li>Reply-To: $sReplyTo</li>\n";
|
||||
$sTestBody .= "</ul>\n";
|
||||
$sTestBody .= "</p>\n";
|
||||
$sTestBody .= "</div>\n";
|
||||
$oEmail->SetBody($sTestBody);
|
||||
$oEmail->SetRecipientTO($this->Get('test_recipient'));
|
||||
$oEmail->SetRecipientFrom($this->Get('test_recipient'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$oEmail->SetSubject($sSubject);
|
||||
$oEmail->SetBody($sBody);
|
||||
$oEmail->SetRecipientTO($sTo);
|
||||
$oEmail->SetRecipientCC($sCC);
|
||||
$oEmail->SetRecipientBCC($sBCC);
|
||||
$oEmail->SetRecipientFrom($sFrom);
|
||||
$oEmail->SetRecipientReplyTo($sReplyTo);
|
||||
}
|
||||
|
||||
if (empty($this->m_aMailErrors))
|
||||
{
|
||||
if ($this->m_iRecipients == 0)
|
||||
{
|
||||
$this->m_aMailErrors[] = 'No recipient';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->m_aMailErrors = array_merge($this->m_aMailErrors, $oEmail->Send());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$this->m_aMailErrors[] = $e->getMessage();
|
||||
}
|
||||
|
||||
$oLog = new EventNotificationEmail();
|
||||
if (empty($this->m_aMailErrors))
|
||||
{
|
||||
if ($this->IsBeingTested())
|
||||
{
|
||||
$oLog->Set('message', 'TEST - Notification sent ('.$this->Get('test_recipient').')');
|
||||
}
|
||||
else
|
||||
{
|
||||
$oLog->Set('message', 'Notification sent');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_array($this->m_aMailErrors) && count($this->m_aMailErrors) > 0)
|
||||
{
|
||||
$sError = implode(', ', $this->m_aMailErrors);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sError = 'Unknown reason';
|
||||
}
|
||||
if ($this->IsBeingTested())
|
||||
{
|
||||
$oLog->Set('message', 'TEST - Notification was not sent: '.$sError);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oLog->Set('message', 'Notification was not sent: '.$sError);
|
||||
}
|
||||
}
|
||||
|
||||
$oLog->Set('userinfo', UserRights::GetUser());
|
||||
$oLog->Set('trigger_id', $oTrigger->GetKey());
|
||||
$oLog->Set('action_id', $this->GetKey());
|
||||
$oLog->Set('object_id', $aContextArgs['this->id']);
|
||||
|
||||
// Note: we have to secure this because those values are calculated
|
||||
// inside the try statement, and we would like to keep track of as
|
||||
// many data as we could while some variables may still be undefined
|
||||
if (isset($sTo)) $oLog->Set('to', $sTo);
|
||||
if (isset($sCC)) $oLog->Set('cc', $sCC);
|
||||
if (isset($sBCC)) $oLog->Set('bcc', $sBCC);
|
||||
if (isset($sFrom)) $oLog->Set('from', $sFrom);
|
||||
if (isset($sSubject)) $oLog->Set('subject', $sSubject);
|
||||
if (isset($sBody)) $oLog->Set('body', $sBody);
|
||||
$oLog->DBInsertNoReload();
|
||||
}
|
||||
}
|
||||
?>
|
||||
323
core/archive.class.inc.php
Normal file
323
core/archive.class.inc.php
Normal file
@@ -0,0 +1,323 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* archive.class.inc.php
|
||||
* Utility to import/export the DB from/to a ZIP file
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
/**
|
||||
* iTopArchive a class to manipulate (read/write) iTop archives with their catalog
|
||||
* Each iTop archive is a zip file that contains (at the root of the archive)
|
||||
* a file called catalog.xml holding the description of the archive
|
||||
*/
|
||||
class iTopArchive
|
||||
{
|
||||
const read = 0;
|
||||
const create = ZipArchive::CREATE;
|
||||
|
||||
protected $m_sZipPath;
|
||||
protected $m_oZip;
|
||||
protected $m_sVersion;
|
||||
protected $m_sTitle;
|
||||
protected $m_sDescription;
|
||||
protected $m_aPackages;
|
||||
protected $m_aErrorMessages;
|
||||
|
||||
/**
|
||||
* Construct an iTopArchive object
|
||||
* @param $sArchivePath string The full path the archive file
|
||||
* @param $iMode integrer Either iTopArchive::read for reading an existing archive or iTopArchive::create for creating a new one. Updating is not supported (yet)
|
||||
*/
|
||||
public function __construct($sArchivePath, $iMode = iTopArchive::read)
|
||||
{
|
||||
$this->m_sZipPath = $sArchivePath;
|
||||
$this->m_oZip = new ZipArchive();
|
||||
$this->m_oZip->open($this->m_sZipPath, $iMode);
|
||||
$this->m_aErrorMessages = array();
|
||||
$this->m_sVersion = '1.0';
|
||||
$this->m_sTitle = '';
|
||||
$this->m_sDescription = '';
|
||||
$this->m_aPackages = array();
|
||||
}
|
||||
|
||||
public function SetTitle($sTitle)
|
||||
{
|
||||
$this->m_sTitle = $sTitle;
|
||||
}
|
||||
|
||||
public function SetDescription($sDescription)
|
||||
{
|
||||
$this->m_sDescription = $sDescription;
|
||||
}
|
||||
|
||||
public function GetTitle()
|
||||
{
|
||||
return $this->m_sTitle;
|
||||
}
|
||||
|
||||
public function GetDescription()
|
||||
{
|
||||
return $this->m_sDescription;
|
||||
}
|
||||
|
||||
public function GetPackages()
|
||||
{
|
||||
return $this->m_aPackages;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->m_oZip->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the error message explaining the latest error encountered
|
||||
* @return array All the error messages encountered during the validation
|
||||
*/
|
||||
public function GetErrors()
|
||||
{
|
||||
return $this->m_aErrorMessages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the catalog from the archive (zip) file
|
||||
* @param sPath string Path the the zip file
|
||||
* @return boolean True in case of success, false otherwise
|
||||
*/
|
||||
public function ReadCatalog()
|
||||
{
|
||||
if ($this->IsValid())
|
||||
{
|
||||
$sXmlCatalog = $this->m_oZip->getFromName('catalog.xml');
|
||||
$oParser = xml_parser_create();
|
||||
xml_parse_into_struct($oParser, $sXmlCatalog, $aValues, $aIndexes);
|
||||
xml_parser_free($oParser);
|
||||
|
||||
$iIndex = $aIndexes['ARCHIVE'][0];
|
||||
$this->m_sVersion = $aValues[$iIndex]['attributes']['VERSION'];
|
||||
$iIndex = $aIndexes['TITLE'][0];
|
||||
$this->m_sTitle = $aValues[$iIndex]['value'];
|
||||
$iIndex = $aIndexes['DESCRIPTION'][0];
|
||||
if (array_key_exists('value', $aValues[$iIndex]))
|
||||
{
|
||||
// #@# implement a get_array_value(array, key, default) ?
|
||||
$this->m_sDescription = $aValues[$iIndex]['value'];
|
||||
}
|
||||
|
||||
foreach($aIndexes['PACKAGE'] as $iIndex)
|
||||
{
|
||||
$this->m_aPackages[$aValues[$iIndex]['attributes']['HREF']] = array( 'type' => $aValues[$iIndex]['attributes']['TYPE'], 'title'=> $aValues[$iIndex]['attributes']['TITLE'], 'description' => $aValues[$iIndex]['value']);
|
||||
}
|
||||
|
||||
//echo "Archive path: {$this->m_sZipPath}<br/>\n";
|
||||
//echo "Archive format version: {$this->m_sVersion}<br/>\n";
|
||||
//echo "Title: {$this->m_sTitle}<br/>\n";
|
||||
//echo "Description: {$this->m_sDescription}<br/>\n";
|
||||
//foreach($this->m_aPackages as $aFile)
|
||||
//{
|
||||
// echo "{$aFile['title']} ({$aFile['type']}): {$aFile['description']}<br/>\n";
|
||||
//}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function WriteCatalog()
|
||||
{
|
||||
$sXml = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?".">\n"; // split the XML closing tag that disturbs PSPad's syntax coloring
|
||||
$sXml .= "<archive version=\"1.0\">\n";
|
||||
$sXml .= "<title>{$this->m_sTitle}</title>\n";
|
||||
$sXml .= "<description>{$this->m_sDescription}</description>\n";
|
||||
foreach($this->m_aPackages as $sFileName => $aFile)
|
||||
{
|
||||
$sXml .= "<package title=\"{$aFile['title']}\" type=\"{$aFile['type']}\" href=\"$sFileName\">{$aFile['description']}</package>\n";
|
||||
}
|
||||
$sXml .= "</archive>";
|
||||
$this->m_oZip->addFromString('catalog.xml', $sXml);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a package to the archive
|
||||
* @param string $sExternalFilePath The path to the file to be added to the archive as a package (directories are not yet implemented)
|
||||
* @param string $sFilePath The name of the file inside the archive
|
||||
* @param string $sTitle A short title for this package
|
||||
* @param string $sType Type of the package. SQL scripts must be of type 'text/sql'
|
||||
* @param string $sDescription A longer description of the purpose of this package
|
||||
* @return none
|
||||
*/
|
||||
public function AddPackage($sExternalFilePath, $sFilePath, $sTitle, $sType, $sDescription)
|
||||
{
|
||||
$this->m_aPackages[$sFilePath] = array('title' => $sTitle, 'type' => $sType, 'description' => $sDescription);
|
||||
$this->m_oZip->addFile($sExternalFilePath, $sFilePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the contents of the given file from the archive
|
||||
* @param string $sFileName The path to the file inside the archive
|
||||
* @return string The content of the file read from the archive
|
||||
*/
|
||||
public function GetFileContents($sFileName)
|
||||
{
|
||||
return $this->m_oZip->getFromName($sFileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the contents of the given file from the archive
|
||||
* @param string $sFileName The path to the file inside the archive
|
||||
* @param string $sDestinationFileName The path of the file to write
|
||||
* @return none
|
||||
*/
|
||||
public function ExtractToFile($sFileName, $sDestinationFileName)
|
||||
{
|
||||
$iBufferSize = 64 * 1024; // Read 64K at a time
|
||||
$oZipStream = $this->m_oZip->getStream($sFileName);
|
||||
$oDestinationStream = fopen($sDestinationFileName, 'wb');
|
||||
while (!feof($oZipStream)) {
|
||||
$sContents = fread($oZipStream, $iBufferSize);
|
||||
fwrite($oDestinationStream, $sContents);
|
||||
}
|
||||
fclose($oZipStream);
|
||||
fclose($oDestinationStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a SQL script taken from the archive. The package must be listed in the catalog and of type text/sql
|
||||
* @param string $sFileName The path to the SQL package inside the archive
|
||||
* @return boolean false in case of error, true otherwise
|
||||
*/
|
||||
public function ImportSql($sFileName, $sDatabase = 'itop')
|
||||
{
|
||||
if ( ($this->m_oZip->locateName($sFileName) == false) || (!isset($this->m_aPackages[$sFileName])) || ($this->m_aPackages[$sFileName]['type'] != 'text/sql'))
|
||||
{
|
||||
// invalid type or not listed in the catalog
|
||||
return false;
|
||||
}
|
||||
$sTempName = tempnam("../tmp/", "sql");
|
||||
//echo "Extracting to: '$sTempName'<br/>\n";
|
||||
$this->ExtractToFile($sFileName, $sTempName);
|
||||
// Note: the command line below works on Windows with the right path to mysql !!!
|
||||
$sCommandLine = 'type "'.$sTempName.'" | "/iTop/MySQL Server 5.0/bin/mysql.exe" -u root '.$sDatabase;
|
||||
//echo "Executing: '$sCommandLine'<br/>\n";
|
||||
exec($sCommandLine, $aOutput, $iRet);
|
||||
//echo "Return code: $iRet<br/>\n";
|
||||
//echo "Output:<br/><pre>\n";
|
||||
//print_r($aOutput);
|
||||
//echo "</pre><br/>\n";
|
||||
unlink($sTempName);
|
||||
return ($iRet == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps some part of the specified MySQL database into the archive as a text/sql package
|
||||
* @param $sTitle string A short title for this SQL script
|
||||
* @param $sDescription string A longer description of the purpose of this SQL script
|
||||
* @param $sFileName string The name of the package inside the archive
|
||||
* @param $sDatabase string name of the database
|
||||
* @param $aTables array array or table names. If empty, all tables are dumped
|
||||
* @param $bStructureOnly boolean Whether or not to dump the data or just the schema
|
||||
* @return boolean False in case of error, true otherwise
|
||||
*/
|
||||
public function AddDatabaseDump($sTitle, $sDescription, $sFileName, $sDatabase = 'itop', $aTables = array(), $bStructureOnly = true)
|
||||
{
|
||||
$sTempName = tempnam("../tmp/", "sql");
|
||||
$sNoData = $bStructureOnly ? "--no-data" : "";
|
||||
$sCommandLine = "\"/iTop/MySQL Server 5.0/bin/mysqldump.exe\" --user=root --opt $sNoData --result-file=$sTempName $sDatabase ".implode(" ", $aTables);
|
||||
//echo "Executing command: '$sCommandLine'<br/>\n";
|
||||
exec($sCommandLine, $aOutput, $iRet);
|
||||
//echo "Return code: $iRet<br/>\n";
|
||||
//echo "Output:<br/><pre>\n";
|
||||
//print_r($aOutput);
|
||||
//echo "</pre><br/>\n";
|
||||
if ($iRet == 0)
|
||||
{
|
||||
$this->AddPackage($sTempName, $sFileName, $sTitle, 'text/sql', $sDescription);
|
||||
}
|
||||
//unlink($sTempName);
|
||||
return ($iRet == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the consistency of the archive
|
||||
* @return boolean True if the archive file is consistent
|
||||
*/
|
||||
public function IsValid()
|
||||
{
|
||||
// TO DO: use a DTD to validate the XML instead of this hand-made validation
|
||||
$bResult = true;
|
||||
$aMandatoryTags = array('ARCHIVE' => array('VERSION'),
|
||||
'TITLE' => array(),
|
||||
'DESCRIPTION' => array(),
|
||||
'PACKAGE' => array('TYPE', 'HREF', 'TITLE'));
|
||||
|
||||
$sXmlCatalog = $this->m_oZip->getFromName('catalog.xml');
|
||||
$oParser = xml_parser_create();
|
||||
xml_parse_into_struct($oParser, $sXmlCatalog, $aValues, $aIndexes);
|
||||
xml_parser_free($oParser);
|
||||
|
||||
foreach($aMandatoryTags as $sTag => $aAttributes)
|
||||
{
|
||||
// Check that all the required tags are present
|
||||
if (!isset($aIndexes[$sTag]))
|
||||
{
|
||||
$this->m_aErrorMessages[] = "The XML catalog does not contain the mandatory tag $sTag.";
|
||||
$bResult = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($aIndexes[$sTag] as $iIndex)
|
||||
{
|
||||
switch($aValues[$iIndex]['type'])
|
||||
{
|
||||
case 'complete':
|
||||
case 'open':
|
||||
// Check that all the required attributes are present
|
||||
foreach($aAttributes as $sAttribute)
|
||||
{
|
||||
if (!isset($aValues[$iIndex]['attributes'][$sAttribute]))
|
||||
{
|
||||
$this->m_aErrorMessages[] = "The tag $sTag ($iIndex) does not contain the required attribute $sAttribute.";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// ignore other type of tags: close or cdata
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $bResult;
|
||||
}
|
||||
}
|
||||
/*
|
||||
// Unit test - reading an archive
|
||||
$sArchivePath = '../tmp/archive.zip';
|
||||
$oArchive = new iTopArchive($sArchivePath, iTopArchive::read);
|
||||
$oArchive->ReadCatalog();
|
||||
$oArchive->ImportSql('full_backup.sql');
|
||||
|
||||
// Writing an archive --
|
||||
|
||||
$sArchivePath = '../tmp/archive2.zip';
|
||||
$oArchive = new iTopArchive($sArchivePath, iTopArchive::create);
|
||||
$oArchive->SetTitle('First Archive !');
|
||||
$oArchive->SetDescription('This is just a test. Does not contain a lot of useful data.');
|
||||
$oArchive->AddPackage('../tmp/schema.sql', 'test.sql', 'this is just a test', 'text/sql', 'My first attempt at creating an archive from PHP...');
|
||||
$oArchive->WriteCatalog();
|
||||
|
||||
|
||||
$sArchivePath = '../tmp/archive2.zip';
|
||||
$oArchive = new iTopArchive($sArchivePath, iTopArchive::create);
|
||||
$oArchive->SetTitle('First Archive !');
|
||||
$oArchive->SetDescription('This is just a test. Does not contain a lot of useful data.');
|
||||
$oArchive->AddDatabaseDump('Test', 'This is my first automatic dump', 'schema.sql', 'itop', array('objects'));
|
||||
$oArchive->WriteCatalog();
|
||||
*/
|
||||
?>
|
||||
1409
core/attributedef.class.inc.php
Normal file
1409
core/attributedef.class.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
515
core/bulkchange.class.inc.php
Normal file
515
core/bulkchange.class.inc.php
Normal file
@@ -0,0 +1,515 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* BulkChange
|
||||
* Interpret a given data set and update the DB accordingly (fake mode avail.)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
class BulkChangeException extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* CellChangeSpec
|
||||
* A series of classes, keeping the information about a given cell: could it be changed or not (and why)?
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
abstract class CellChangeSpec
|
||||
{
|
||||
protected $m_proposedValue;
|
||||
|
||||
public function __construct($proposedValue)
|
||||
{
|
||||
$this->m_proposedValue = $proposedValue;
|
||||
}
|
||||
|
||||
static protected function ValueAsHtml($value)
|
||||
{
|
||||
if (MetaModel::IsValidObject($value))
|
||||
{
|
||||
return $value->GetHyperLink();
|
||||
}
|
||||
else
|
||||
{
|
||||
return htmlentities($value);
|
||||
}
|
||||
}
|
||||
|
||||
public function GetValue($bHtml = false)
|
||||
{
|
||||
if ($bHtml)
|
||||
{
|
||||
return self::ValueAsHtml($this->m_proposedValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->m_proposedValue;
|
||||
}
|
||||
}
|
||||
|
||||
abstract public function GetDescription($bHtml = false);
|
||||
}
|
||||
|
||||
|
||||
class CellChangeSpec_Void extends CellChangeSpec
|
||||
{
|
||||
public function GetDescription($bHtml = false)
|
||||
{
|
||||
return $this->GetValue($bHtml);
|
||||
}
|
||||
}
|
||||
|
||||
class CellChangeSpec_Unchanged extends CellChangeSpec
|
||||
{
|
||||
public function GetDescription($bHtml = false)
|
||||
{
|
||||
return $this->GetValue($bHtml)." (unchanged)";
|
||||
}
|
||||
}
|
||||
|
||||
class CellChangeSpec_Init extends CellChangeSpec
|
||||
{
|
||||
public function GetDescription($bHtml = false)
|
||||
{
|
||||
return $this->GetValue($bHtml);
|
||||
}
|
||||
}
|
||||
|
||||
class CellChangeSpec_Modify extends CellChangeSpec
|
||||
{
|
||||
protected $m_previousValue;
|
||||
|
||||
public function __construct($proposedValue, $previousValue)
|
||||
{
|
||||
$this->m_previousValue = $previousValue;
|
||||
parent::__construct($proposedValue);
|
||||
}
|
||||
|
||||
public function GetDescription($bHtml = false)
|
||||
{
|
||||
return $this->GetValue($bHtml)." (previous: ".self::ValueAsHtml($this->m_previousValue).")";
|
||||
}
|
||||
}
|
||||
|
||||
class CellChangeSpec_Issue extends CellChangeSpec_Modify
|
||||
{
|
||||
protected $m_sReason;
|
||||
|
||||
public function __construct($proposedValue, $previousValue, $sReason)
|
||||
{
|
||||
$this->m_sReason = $sReason;
|
||||
parent::__construct($proposedValue, $previousValue);
|
||||
}
|
||||
|
||||
public function GetDescription($bHtml = false)
|
||||
{
|
||||
if (is_null($this->m_proposedValue))
|
||||
{
|
||||
return 'Could not be changed - reason: '.$this->m_sReason;
|
||||
}
|
||||
return 'Could not be changed to "'.$this->GetValue($bHtml).'" - reason: '.$this->m_sReason.' (previous: '.$this->m_previousValue.')';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* RowStatus
|
||||
* A series of classes, keeping the information about a given row: could it be changed or not (and why)?
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
abstract class RowStatus
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
abstract public function GetDescription($bHtml = false);
|
||||
}
|
||||
|
||||
class RowStatus_NoChange extends RowStatus
|
||||
{
|
||||
public function GetDescription($bHtml = false)
|
||||
{
|
||||
return "unchanged";
|
||||
}
|
||||
}
|
||||
|
||||
class RowStatus_NewObj extends RowStatus
|
||||
{
|
||||
protected $m_iObjKey;
|
||||
|
||||
public function __construct($sClass = '', $iObjKey = null)
|
||||
{
|
||||
$this->m_iObjKey = $iObjKey;
|
||||
$this->m_sClass = $sClass;
|
||||
}
|
||||
|
||||
public function GetDescription($bHtml = false)
|
||||
{
|
||||
if (is_null($this->m_iObjKey))
|
||||
{
|
||||
return "Create";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!empty($this->m_sClass))
|
||||
{
|
||||
$oObj = MetaModel::GetObject($this->m_sClass, $this->m_iObjKey);
|
||||
return 'Created '.$oObj->GetHyperLink();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'Created (id: '.$this->m_iObjKey.')';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RowStatus_Modify extends RowStatus
|
||||
{
|
||||
protected $m_iChanged;
|
||||
|
||||
public function __construct($iChanged)
|
||||
{
|
||||
$this->m_iChanged = $iChanged;
|
||||
}
|
||||
|
||||
public function GetDescription($bHtml = false)
|
||||
{
|
||||
return "update ".$this->m_iChanged." cols";
|
||||
}
|
||||
}
|
||||
|
||||
class RowStatus_Issue extends RowStatus
|
||||
{
|
||||
protected $m_sReason;
|
||||
|
||||
public function __construct($sReason)
|
||||
{
|
||||
$this->m_sReason = $sReason;
|
||||
}
|
||||
|
||||
public function GetDescription($bHtml = false)
|
||||
{
|
||||
return 'Skipped - reason:'.$this->m_sReason;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** BulkChange *
|
||||
** @package iTopORM
|
||||
** @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
** @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
** @link www.itop.com
|
||||
** @since 1.0
|
||||
** @version $itopversion$ */
|
||||
class BulkChange
|
||||
{
|
||||
protected $m_sClass;
|
||||
protected $m_aData; // Note: hereafter, iCol maybe actually be any acceptable key (string)
|
||||
// #@# todo: rename the variables to sColIndex
|
||||
protected $m_aAttList; // attcode => iCol
|
||||
protected $m_aReconcilKeys;// iCol => attcode (attcode = 'id' for the pkey)
|
||||
protected $m_aExtKeys; // aExtKeys[sExtKeyAttCode][sExtReconcKeyAttCode] = iCol;
|
||||
|
||||
public function __construct($sClass, $aData, $aAttList, $aReconcilKeys, $aExtKeys)
|
||||
{
|
||||
$this->m_sClass = $sClass;
|
||||
$this->m_aData = $aData;
|
||||
$this->m_aAttList = $aAttList;
|
||||
$this->m_aReconcilKeys = $aReconcilKeys;
|
||||
$this->m_aExtKeys = $aExtKeys;
|
||||
}
|
||||
|
||||
static protected function MakeSpecObject($sClass, $iId)
|
||||
{
|
||||
$oObj = MetaModel::GetObject($sClass, $iId);
|
||||
if (is_null($oObj))
|
||||
{
|
||||
return $iId;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $oObj;
|
||||
}
|
||||
}
|
||||
|
||||
protected function PrepareObject(&$oTargetObj, $aRowData, &$aErrors)
|
||||
{
|
||||
$aResults = array();
|
||||
$aErrors = array();
|
||||
|
||||
// External keys reconciliation
|
||||
//
|
||||
foreach($this->m_aExtKeys as $sAttCode => $aKeyConfig)
|
||||
{
|
||||
$oExtKey = MetaModel::GetAttributeDef(get_class($oTargetObj), $sAttCode);
|
||||
$oReconFilter = new CMDBSearchFilter($oExtKey->GetTargetClass());
|
||||
foreach ($aKeyConfig as $sForeignAttCode => $iCol)
|
||||
{
|
||||
// The foreign attribute is one of our reconciliation key
|
||||
$oReconFilter->AddCondition($sForeignAttCode, $aRowData[$iCol], '=');
|
||||
$aResults["col$iCol"] = new CellChangeSpec_Void($aRowData[$iCol]);
|
||||
}
|
||||
$oExtObjects = new CMDBObjectSet($oReconFilter);
|
||||
switch($oExtObjects->Count())
|
||||
{
|
||||
case 0:
|
||||
$aErrors[$sAttCode] = "Object not found";
|
||||
$aResults[$sAttCode]= new CellChangeSpec_Issue(null, $oTargetObj->Get($sAttCode), 'Object not found - check the spelling (no space before/after)');
|
||||
break;
|
||||
case 1:
|
||||
// Do change the external key attribute
|
||||
$oForeignObj = $oExtObjects->Fetch();
|
||||
$oTargetObj->Set($sAttCode, $oForeignObj->GetKey());
|
||||
|
||||
// Report it
|
||||
if (array_key_exists($sAttCode, $oTargetObj->ListChanges()))
|
||||
{
|
||||
|
||||
if ($oTargetObj->IsNew())
|
||||
{
|
||||
$aResults[$sAttCode]= new CellChangeSpec_Init($oForeignObj);
|
||||
}
|
||||
else
|
||||
{
|
||||
$previousValue = self::MakeSpecObject($oExtKey->GetTargetClass(), $oTargetObj->GetOriginal($sAttCode));
|
||||
$aResults[$sAttCode]= new CellChangeSpec_Modify($oForeignObj, $previousValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aResults[$sAttCode]= new CellChangeSpec_Unchanged($oForeignObj);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$aErrors[$sAttCode] = "Found ".$oExtObjects->Count()." matches";
|
||||
$previousValue = self::MakeSpecObject($oExtKey->GetTargetClass(), $oTargetObj->Get($sAttCode));
|
||||
$aResults[$sAttCode]= new CellChangeSpec_Issue(null, $previousValue, "Found ".$oExtObjects->Count()." matches");
|
||||
}
|
||||
}
|
||||
|
||||
// Set the object attributes
|
||||
//
|
||||
foreach ($this->m_aAttList as $sAttCode => $iCol)
|
||||
{
|
||||
// skip the private key, if any
|
||||
if ($sAttCode == 'id') continue;
|
||||
|
||||
if (!$oTargetObj->CheckValue($sAttCode, $aRowData[$iCol]))
|
||||
{
|
||||
$aErrors[$sAttCode] = "Unexpected value";
|
||||
}
|
||||
else
|
||||
{
|
||||
$oTargetObj->Set($sAttCode, $aRowData[$iCol]);
|
||||
}
|
||||
}
|
||||
|
||||
// Reporting on fields
|
||||
//
|
||||
$aChangedFields = $oTargetObj->ListChanges();
|
||||
foreach ($this->m_aAttList as $sAttCode => $iCol)
|
||||
{
|
||||
if ($sAttCode == 'id')
|
||||
{
|
||||
if ($aRowData[$iCol] == $oTargetObj->GetKey())
|
||||
{
|
||||
$aResults["col$iCol"]= new CellChangeSpec_Void($aRowData[$iCol]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aResults["col$iCol"]= new CellChangeSpec_Init($aRowData[$iCol]);
|
||||
}
|
||||
|
||||
}
|
||||
if (isset($aErrors[$sAttCode]))
|
||||
{
|
||||
$aResults["col$iCol"]= new CellChangeSpec_Issue($oTargetObj->Get($sAttCode), $oTargetObj->GetOriginal($sAttCode), $aErrors[$sAttCode]);
|
||||
}
|
||||
elseif (array_key_exists($sAttCode, $aChangedFields))
|
||||
{
|
||||
if ($oTargetObj->IsNew())
|
||||
{
|
||||
$aResults["col$iCol"]= new CellChangeSpec_Init($oTargetObj->Get($sAttCode));
|
||||
}
|
||||
else
|
||||
{
|
||||
$aResults["col$iCol"]= new CellChangeSpec_Modify($oTargetObj->Get($sAttCode), $oTargetObj->GetOriginal($sAttCode));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// By default... nothing happens
|
||||
$aResults["col$iCol"]= new CellChangeSpec_Void($aRowData[$iCol]);
|
||||
}
|
||||
}
|
||||
|
||||
// Checks
|
||||
//
|
||||
if (!$oTargetObj->CheckConsistency())
|
||||
{
|
||||
$aErrors["GLOBAL"] = "Attributes not consistent with each others";
|
||||
}
|
||||
return $aResults;
|
||||
}
|
||||
|
||||
|
||||
protected function CreateObject(&$aResult, $iRow, $aRowData, CMDBChange $oChange = null)
|
||||
{
|
||||
$oTargetObj = MetaModel::NewObject($this->m_sClass);
|
||||
$aResult[$iRow] = $this->PrepareObject($oTargetObj, $aRowData, $aErrors);
|
||||
|
||||
if (count($aErrors) > 0)
|
||||
{
|
||||
$sErrors = implode(', ', $aErrors);
|
||||
$aResult[$iRow]["__STATUS__"] = new RowStatus_Issue("Unexpected attribute value(s)");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that any external key will have a value proposed
|
||||
$aMissingKeys = array();
|
||||
foreach (MetaModel::GetExternalKeys($this->m_sClass) as $sExtKeyAttCode => $oExtKey)
|
||||
{
|
||||
if (!$oExtKey->IsNullAllowed())
|
||||
{
|
||||
if (!array_key_exists($sExtKeyAttCode, $this->m_aExtKeys) && !array_key_exists($sExtKeyAttCode, $this->m_aAttList))
|
||||
{
|
||||
$aMissingKeys[] = $oExtKey->GetLabel();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count($aMissingKeys) > 0)
|
||||
{
|
||||
$sMissingKeys = implode(', ', $aMissingKeys);
|
||||
$aResult[$iRow]["__STATUS__"] = new RowStatus_Issue("Could not be created, due to missing external key(s): $sMissingKeys");
|
||||
return;
|
||||
}
|
||||
|
||||
// Optionaly record the results
|
||||
//
|
||||
if ($oChange)
|
||||
{
|
||||
$newID = $oTargetObj->DBInsertTrackedNoReload($oChange);
|
||||
$aResult[$iRow]["__STATUS__"] = new RowStatus_NewObj($this->m_sClass, $newID);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aResult[$iRow]["__STATUS__"] = new RowStatus_NewObj();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function UpdateObject(&$aResult, $iRow, $oTargetObj, $aRowData, CMDBChange $oChange = null)
|
||||
{
|
||||
$aResult[$iRow] = $this->PrepareObject($oTargetObj, $aRowData, $aErrors);
|
||||
|
||||
// Reporting
|
||||
//
|
||||
if (count($aErrors) > 0)
|
||||
{
|
||||
$sErrors = implode(', ', $aErrors);
|
||||
$aResult[$iRow]["__STATUS__"] = new RowStatus_Issue("Unexpected attribute value(s)");
|
||||
return;
|
||||
}
|
||||
|
||||
$aChangedFields = $oTargetObj->ListChanges();
|
||||
if (count($aChangedFields) > 0)
|
||||
{
|
||||
$aResult[$iRow]["__STATUS__"] = new RowStatus_Modify(count($aChangedFields));
|
||||
|
||||
// Optionaly record the results
|
||||
//
|
||||
if ($oChange)
|
||||
{
|
||||
$oTargetObj->DBUpdateTracked($oChange);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aResult[$iRow]["__STATUS__"] = new RowStatus_NoChange();
|
||||
}
|
||||
}
|
||||
|
||||
public function Process(CMDBChange $oChange = null)
|
||||
{
|
||||
// Note: $oChange can be null, in which case the aim is to check what would be done
|
||||
|
||||
// Compute the results
|
||||
//
|
||||
$aResult = array();
|
||||
foreach($this->m_aData as $iRow => $aRowData)
|
||||
{
|
||||
$oReconciliationFilter = new CMDBSearchFilter($this->m_sClass);
|
||||
foreach($this->m_aReconcilKeys as $sAttCode)
|
||||
{
|
||||
$iCol = $this->m_aAttList[$sAttCode];
|
||||
$oReconciliationFilter->AddCondition($sAttCode, $aRowData[$iCol], '=');
|
||||
}
|
||||
$oReconciliationSet = new CMDBObjectSet($oReconciliationFilter);
|
||||
switch($oReconciliationSet->Count())
|
||||
{
|
||||
case 0:
|
||||
$this->CreateObject($aResult, $iRow, $aRowData, $oChange);
|
||||
// $aResult[$iRow]["__STATUS__"]=> set in CreateObject
|
||||
$aResult[$iRow]["__RECONCILIATION__"] = "Object not found";
|
||||
break;
|
||||
case 1:
|
||||
$oTargetObj = $oReconciliationSet->Fetch();
|
||||
$this->UpdateObject($aResult, $iRow, $oTargetObj, $aRowData, $oChange);
|
||||
$aResult[$iRow]["__RECONCILIATION__"] = "Found a match ".$oTargetObj->GetHyperLink();
|
||||
// $aResult[$iRow]["__STATUS__"]=> set in UpdateObject
|
||||
break;
|
||||
default:
|
||||
// Found several matches, ambiguous
|
||||
// Render "void" results on any column
|
||||
foreach($this->m_aExtKeys as $sAttCode => $aKeyConfig)
|
||||
{
|
||||
foreach ($aKeyConfig as $sForeignAttCode => $iCol)
|
||||
{
|
||||
$aResult[$iRow]["col$iCol"] = new CellChangeSpec_Void($aRowData[$iCol]);
|
||||
}
|
||||
$aResult[$iRow][$sAttCode] = new CellChangeSpec_Void('n/a');
|
||||
}
|
||||
foreach ($this->m_aAttList as $sAttCode => $iCol)
|
||||
{
|
||||
$aResult[$iRow]["col$iCol"]= new CellChangeSpec_Void($aRowData[$iCol]);
|
||||
}
|
||||
$aResult[$iRow]["__RECONCILIATION__"] = "Found ".$oReconciliationSet->Count()." matches";
|
||||
$aResult[$iRow]["__STATUS__"]= new RowStatus_Issue("ambiguous reconciliation");
|
||||
}
|
||||
|
||||
// Whatever happened, do report the reconciliation values
|
||||
foreach($this->m_aReconcilKeys as $sAttCode)
|
||||
{
|
||||
$iCol = $this->m_aAttList[$sAttCode];
|
||||
$aResult[$iRow]["col$iCol"] = new CellChangeSpec_Void($aRowData[$iCol]);
|
||||
}
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
44
core/cmdbchange.class.inc.php
Normal file
44
core/cmdbchange.class.inc.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* A change as requested/validated at once by user, may groups many atomic changes
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class CMDBChange extends DBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "change",
|
||||
"description" => "Changes tracking",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "date",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_change",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("date", array("label"=>"date", "description"=>"date and time at which the changes have been recorded", "allowed_values"=>null, "sql"=>"date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("label"=>"misc. info", "description"=>"caller's defined information", "allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("date");
|
||||
MetaModel::Init_AddFilterFromAttribute("userinfo");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
427
core/cmdbchangeop.class.inc.php
Normal file
427
core/cmdbchangeop.class.inc.php
Normal file
@@ -0,0 +1,427 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Various atomic change operations, to be tracked
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
class CMDBChangeOp extends DBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "change operation",
|
||||
"description" => "Change operations tracking",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_changeop",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "optype",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("change", array("label"=>"change", "description"=>"change", "allowed_values"=>null, "sql"=>"changeid", "targetclass"=>"CMDBChange", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("date", array("label"=>"date", "description"=>"date and time of the change", "allowed_values"=>null, "extkey_attcode"=>"change", "target_attcode"=>"date")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("userinfo", array("label"=>"user", "description"=>"who made this change", "allowed_values"=>null, "extkey_attcode"=>"change", "target_attcode"=>"userinfo")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("objclass", array("label"=>"object class", "description"=>"object class", "allowed_values"=>null, "sql"=>"objclass", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("objkey", array("label"=>"object id", "description"=>"object id", "allowed_values"=>null, "sql"=>"objkey", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("objclass");
|
||||
MetaModel::Init_AddFilterFromAttribute("objkey");
|
||||
MetaModel::Init_AddFilterFromAttribute("date");
|
||||
MetaModel::Init_AddFilterFromAttribute("userinfo");
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('change', 'date', 'userinfo')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('change', 'date', 'userinfo')); // Attributes to be displayed for the complete details
|
||||
}
|
||||
/**
|
||||
* Describe (as a text string) the modifications corresponding to this change
|
||||
*/
|
||||
public function GetDescription()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Record the creation of an object
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class CMDBChangeOpCreate extends CMDBChangeOp
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "object creation",
|
||||
"description" => "Object creation tracking",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_changeop_create",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe (as a text string) the modifications corresponding to this change
|
||||
*/
|
||||
public function GetDescription()
|
||||
{
|
||||
return 'Object created';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Record the deletion of an object
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class CMDBChangeOpDelete extends CMDBChangeOp
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "object deletion",
|
||||
"description" => "Object deletion tracking",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_changeop_delete",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
}
|
||||
/**
|
||||
* Describe (as a text string) the modifications corresponding to this change
|
||||
*/
|
||||
public function GetDescription()
|
||||
{
|
||||
return 'Object deleted';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Record the modification of an attribute (abstract)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class CMDBChangeOpSetAttribute extends CMDBChangeOp
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "object change",
|
||||
"description" => "Object properties change tracking",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_changeop_setatt",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("attcode", array("label"=>"Attribute", "description"=>"code of the modified property", "allowed_values"=>null, "sql"=>"attcode", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("attcode");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Record the modification of a scalar attribute
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "property change",
|
||||
"description" => "Object scalar properties change tracking",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_changeop_setatt_scalar",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("oldvalue", array("label"=>"Previous value", "description"=>"previous value of the attribute", "allowed_values"=>null, "sql"=>"oldvalue", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("newvalue", array("label"=>"New value", "description"=>"new value of the attribute", "allowed_values"=>null, "sql"=>"newvalue", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("oldvalue");
|
||||
MetaModel::Init_AddFilterFromAttribute("newvalue");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for a list
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe (as a text string) the modifications corresponding to this change
|
||||
*/
|
||||
public function GetDescription()
|
||||
{
|
||||
// Temporary, until we change the options of GetDescription() -needs a more global revision
|
||||
$bIsHtml = true;
|
||||
|
||||
$sResult = '';
|
||||
$oTargetObjectClass = $this->Get('objclass');
|
||||
$oTargetObjectKey = $this->Get('objkey');
|
||||
$oTargetSearch = new DBObjectSearch($oTargetObjectClass);
|
||||
$oTargetSearch->AddCondition('id', $oTargetObjectKey);
|
||||
|
||||
$oMonoObjectSet = new DBObjectSet($oTargetSearch);
|
||||
if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->Get('objclass'), $this->Get('attcode'));
|
||||
$sAttName = $oAttDef->GetLabel();
|
||||
$sNewValue = $this->Get('newvalue');
|
||||
$sOldValue = $this->Get('oldvalue');
|
||||
if ( (($oAttDef->GetType() == 'String') || ($oAttDef->GetType() == 'Text')) &&
|
||||
(strlen($sNewValue) > strlen($sOldValue)) )
|
||||
{
|
||||
// Check if some text was not appended to the field
|
||||
if (substr($sNewValue,0, strlen($sOldValue)) == $sOldValue) // Text added at the end
|
||||
{
|
||||
$sDelta = substr($sNewValue, strlen($sOldValue));
|
||||
$sResult = "$sDelta appended to $sAttName";
|
||||
}
|
||||
else if (substr($sNewValue, -strlen($sOldValue)) == $sOldValue) // Text added at the beginning
|
||||
{
|
||||
$sDelta = substr($sNewValue, 0, strlen($sNewValue) - strlen($sOldValue));
|
||||
$sResult = "$sDelta appended to $sAttName";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult = "$sAttName set to $sNewValue (previous value: $sOldValue)";
|
||||
}
|
||||
}
|
||||
elseif($bIsHtml && $oAttDef->IsExternalKey())
|
||||
{
|
||||
$sTargetClass = $oAttDef->GetTargetClass();
|
||||
$sFrom = MetaModel::GetHyperLink($sTargetClass, $sOldValue);
|
||||
$sTo = MetaModel::GetHyperLink($sTargetClass, $sNewValue);
|
||||
$sResult = "$sAttName set to $sTo (previous: $sFrom)";
|
||||
}
|
||||
elseif ($oAttDef instanceOf AttributeBlob)
|
||||
{
|
||||
$sResult = "#@# Issue... found an attribute for which other type of tracking should be made";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult = "$sAttName set to $sNewValue (previous value: $sOldValue)";
|
||||
}
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Record the modification of a blob
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class CMDBChangeOpSetAttributeBlob extends CMDBChangeOpSetAttribute
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "data change",
|
||||
"description" => "data change tracking",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_changeop_setatt_data",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeBlob("prevdata", array("label"=>"Previous data", "description"=>"previous contents of the attribute", "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe (as a text string) the modifications corresponding to this change
|
||||
*/
|
||||
public function GetDescription()
|
||||
{
|
||||
// Temporary, until we change the options of GetDescription() -needs a more global revision
|
||||
$bIsHtml = true;
|
||||
|
||||
$sResult = '';
|
||||
$oTargetObjectClass = $this->Get('objclass');
|
||||
$oTargetObjectKey = $this->Get('objkey');
|
||||
$oTargetSearch = new DBObjectSearch($oTargetObjectClass);
|
||||
$oTargetSearch->AddCondition('id', $oTargetObjectKey);
|
||||
|
||||
$oMonoObjectSet = new DBObjectSet($oTargetSearch);
|
||||
if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->Get('objclass'), $this->Get('attcode'));
|
||||
$sAttName = $oAttDef->GetLabel();
|
||||
$oPrevDoc = $this->Get('prevdata');
|
||||
$sDocView = $oPrevDoc->GetAsHtml();
|
||||
$sDocView .= "<br/>Open in New Window: ".$oPrevDoc->GetDisplayLink(get_class($this), $this->GetKey(), 'prevdata').", \n";
|
||||
$sDocView .= "Download: ".$oPrevDoc->GetDownloadLink(get_class($this), $this->GetKey(), 'prevdata')."\n";
|
||||
|
||||
//$sDocView = $oPrevDoc->GetDisplayInline(get_class($this), $this->GetKey(), 'prevdata');
|
||||
$sResult = "$sAttName changed, previous value: $sDocView";
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Record the modification of a multiline string (text)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class CMDBChangeOpSetAttributeText extends CMDBChangeOpSetAttribute
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "text change",
|
||||
"description" => "text change tracking",
|
||||
"key_type" => "",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "change",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_changeop_setatt_text",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeText("prevdata", array("label"=>"Previous data", "description"=>"previous contents of the attribute", "allowed_values"=>null, "sql"=>"prevdata", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe (as a text string) the modifications corresponding to this change
|
||||
*/
|
||||
public function GetDescription()
|
||||
{
|
||||
// Temporary, until we change the options of GetDescription() -needs a more global revision
|
||||
$bIsHtml = true;
|
||||
|
||||
$sResult = '';
|
||||
$oTargetObjectClass = $this->Get('objclass');
|
||||
$oTargetObjectKey = $this->Get('objkey');
|
||||
$oTargetSearch = new DBObjectSearch($oTargetObjectClass);
|
||||
$oTargetSearch->AddCondition('id', $oTargetObjectKey);
|
||||
|
||||
$oMonoObjectSet = new DBObjectSet($oTargetSearch);
|
||||
if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->Get('objclass'), $this->Get('attcode'));
|
||||
$sAttName = $oAttDef->GetLabel();
|
||||
$sTextView = '<div>'.$this->GetAsHtml('prevdata').'</div>';
|
||||
|
||||
//$sDocView = $oPrevDoc->GetDisplayInline(get_class($this), $this->GetKey(), 'prevdata');
|
||||
$sResult = "$sAttName changed, previous value: $sTextView";
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
508
core/cmdbobject.class.inc.php
Normal file
508
core/cmdbobject.class.inc.php
Normal file
@@ -0,0 +1,508 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* cmdbObjectClass
|
||||
* the file to include, then the core is yours
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
require_once('coreexception.class.inc.php');
|
||||
|
||||
require_once('config.class.inc.php');
|
||||
|
||||
require_once('attributedef.class.inc.php');
|
||||
require_once('filterdef.class.inc.php');
|
||||
require_once('stimulus.class.inc.php');
|
||||
require_once('valuesetdef.class.inc.php');
|
||||
require_once('MyHelpers.class.inc.php');
|
||||
|
||||
require_once('expression.class.inc.php');
|
||||
|
||||
require_once('cmdbsource.class.inc.php');
|
||||
require_once('sqlquery.class.inc.php');
|
||||
require_once('oql/oqlquery.class.inc.php');
|
||||
require_once('oql/oqlexception.class.inc.php');
|
||||
require_once('oql/oql-parser.php');
|
||||
require_once('oql/oql-lexer.php');
|
||||
require_once('oql/oqlinterpreter.class.inc.php');
|
||||
|
||||
require_once('dbobject.class.php');
|
||||
require_once('dbobjectsearch.class.php');
|
||||
require_once('dbobjectset.class.php');
|
||||
|
||||
// db change tracking data model
|
||||
require_once('cmdbchange.class.inc.php');
|
||||
require_once('cmdbchangeop.class.inc.php');
|
||||
|
||||
// customization data model
|
||||
// Romain: temporary moved into application.inc.php (see explanations there)
|
||||
//require_once('trigger.class.inc.php');
|
||||
//require_once('action.class.inc.php');
|
||||
|
||||
// application log
|
||||
// Romain: temporary moved into application.inc.php (see explanations there)
|
||||
//require_once('event.class.inc.php');
|
||||
|
||||
require_once('csvparser.class.inc.php');
|
||||
require_once('bulkchange.class.inc.php');
|
||||
|
||||
require_once('userrights.class.inc.php');
|
||||
|
||||
//
|
||||
// Error handling
|
||||
// To be finalized... or removed ?
|
||||
//
|
||||
function cmdbErrorHandler($errno, $errstr, $errfile, $errline)
|
||||
{
|
||||
// font-family: Courier-New, Courier, Arial, Helevtica;
|
||||
$sErrorStyle = "
|
||||
background-color: #ffaaaa;
|
||||
color: #000000;
|
||||
border: 1px dashed #000000;
|
||||
padding: 0.25em;
|
||||
margin-top: 1em;
|
||||
";
|
||||
$sCallStackStyle = "
|
||||
font-size: smaller;
|
||||
background-color: #ffcccc;
|
||||
color: #000000;
|
||||
border: 1px dashed #000000;
|
||||
padding: 0.25em;
|
||||
margin-top: 1em;
|
||||
";
|
||||
|
||||
switch ($errno)
|
||||
{
|
||||
case E_USER_ERROR:
|
||||
case E_ERROR:
|
||||
echo "<div style=\"$sErrorStyle\">\n";
|
||||
echo "<b>Error</b> [$errno] $errstr<br />\n";
|
||||
echo "<div style=\"$sCallStackStyle\">\n";
|
||||
MyHelpers::dump_callstack(1);
|
||||
echo "</div>\n";
|
||||
echo "Hereafter the biz model internals:<br />\n";
|
||||
echo "<pre>\n";
|
||||
MetaModel::static_var_dump();
|
||||
echo "</pre>\n";
|
||||
echo "Aborting...<br />\n";
|
||||
echo "</div>\n";
|
||||
exit(1);
|
||||
break;
|
||||
case E_USER_WARNING:
|
||||
case E_WARNING:
|
||||
echo "<div style=\"background-color:#FAA;\">\n";
|
||||
echo "<b>Warning</b> [$errno] $errstr<br />\n";
|
||||
echo "<div style=\"background-color:#FCC;\">\n";
|
||||
MyHelpers::dump_callstack(1);
|
||||
echo "</div>\n";
|
||||
echo "</div>\n";
|
||||
break;
|
||||
case E_USER_NOTICE:
|
||||
case E_NOTICE:
|
||||
echo "<div style=\"background-color:#FAA;\">\n";
|
||||
echo "<b>Notice</b> [$errno] $errstr<br />\n";
|
||||
echo "<div style=\"background-color:#FCC;\">\n";
|
||||
MyHelpers::dump_callstack(1);
|
||||
echo "</div>\n";
|
||||
echo "</div>\n";
|
||||
break;
|
||||
default:
|
||||
echo "Unknown error type: [$errno] $errstr<br />\n";
|
||||
MyHelpers::dump_callstack(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
//set_error_handler("cmdbErrorHandler");
|
||||
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* A persistent object, which changes are accurately recorded
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
abstract class CMDBObject extends DBObject
|
||||
{
|
||||
protected $m_datCreated;
|
||||
protected $m_datUpdated;
|
||||
protected static $m_oCurrChange = null;
|
||||
|
||||
|
||||
private function RecordObjCreation(CMDBChange $oChange)
|
||||
{
|
||||
$oMyChangeOp = MetaModel::NewObject("CMDBChangeOpCreate");
|
||||
$oMyChangeOp->Set("change", $oChange->GetKey());
|
||||
$oMyChangeOp->Set("objclass", get_class($this));
|
||||
$oMyChangeOp->Set("objkey", $this->GetKey());
|
||||
$iId = $oMyChangeOp->DBInsertNoReload();
|
||||
}
|
||||
private function RecordObjDeletion(CMDBChange $oChange, $objkey)
|
||||
{
|
||||
$oMyChangeOp = MetaModel::NewObject("CMDBChangeOpDelete");
|
||||
$oMyChangeOp->Set("change", $oChange->GetKey());
|
||||
$oMyChangeOp->Set("objclass", get_class($this));
|
||||
$oMyChangeOp->Set("objkey", $objkey);
|
||||
$iId = $oMyChangeOp->DBInsertNoReload();
|
||||
}
|
||||
private function RecordAttChanges(CMDBChange $oChange, array $aValues, array $aOrigValues)
|
||||
{
|
||||
// $aValues is an array of $sAttCode => $value
|
||||
//
|
||||
foreach ($aValues as $sAttCode=> $value)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
|
||||
if ($oAttDef->IsLinkSet()) continue; // #@# temporary
|
||||
|
||||
if ($oAttDef instanceOf AttributeBlob)
|
||||
{
|
||||
// Data blobs
|
||||
$oMyChangeOp = MetaModel::NewObject("CMDBChangeOpSetAttributeBlob");
|
||||
$oMyChangeOp->Set("change", $oChange->GetKey());
|
||||
$oMyChangeOp->Set("objclass", get_class($this));
|
||||
$oMyChangeOp->Set("objkey", $this->GetKey());
|
||||
$oMyChangeOp->Set("attcode", $sAttCode);
|
||||
|
||||
if (array_key_exists($sAttCode, $aOrigValues))
|
||||
{
|
||||
$original = $aOrigValues[$sAttCode];
|
||||
}
|
||||
else
|
||||
{
|
||||
$original = new ormDocument();
|
||||
}
|
||||
$oMyChangeOp->Set("prevdata", $original);
|
||||
$iId = $oMyChangeOp->DBInsertNoReload();
|
||||
}
|
||||
elseif ($oAttDef instanceOf AttributeText)
|
||||
{
|
||||
// Data blobs
|
||||
$oMyChangeOp = MetaModel::NewObject("CMDBChangeOpSetAttributeText");
|
||||
$oMyChangeOp->Set("change", $oChange->GetKey());
|
||||
$oMyChangeOp->Set("objclass", get_class($this));
|
||||
$oMyChangeOp->Set("objkey", $this->GetKey());
|
||||
$oMyChangeOp->Set("attcode", $sAttCode);
|
||||
|
||||
if (array_key_exists($sAttCode, $aOrigValues))
|
||||
{
|
||||
$original = $aOrigValues[$sAttCode];
|
||||
}
|
||||
else
|
||||
{
|
||||
$original = null;
|
||||
}
|
||||
$oMyChangeOp->Set("prevdata", $original);
|
||||
$iId = $oMyChangeOp->DBInsertNoReload();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Scalars
|
||||
//
|
||||
$oMyChangeOp = MetaModel::NewObject("CMDBChangeOpSetAttributeScalar");
|
||||
$oMyChangeOp->Set("change", $oChange->GetKey());
|
||||
$oMyChangeOp->Set("objclass", get_class($this));
|
||||
$oMyChangeOp->Set("objkey", $this->GetKey());
|
||||
$oMyChangeOp->Set("attcode", $sAttCode);
|
||||
|
||||
if (array_key_exists($sAttCode, $aOrigValues))
|
||||
{
|
||||
$sOriginalValue = $aOrigValues[$sAttCode];
|
||||
}
|
||||
else
|
||||
{
|
||||
$sOriginalValue = 'undefined';
|
||||
}
|
||||
$oMyChangeOp->Set("oldvalue", $sOriginalValue);
|
||||
$oMyChangeOp->Set("newvalue", $value);
|
||||
$iId = $oMyChangeOp->DBInsertNoReload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function DBInsert()
|
||||
{
|
||||
if(!is_object(self::$m_oCurrChange))
|
||||
{
|
||||
throw new CoreException("DBInsert() could not be used here, please use DBInsertTracked() instead");
|
||||
}
|
||||
return $this->DBInsertTracked_Internal();
|
||||
}
|
||||
|
||||
public function DBInsertTracked(CMDBChange $oChange)
|
||||
{
|
||||
self::$m_oCurrChange = $oChange;
|
||||
$ret = $this->DBInsertTracked_Internal();
|
||||
self::$m_oCurrChange = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function DBInsertTrackedNoReload(CMDBChange $oChange)
|
||||
{
|
||||
self::$m_oCurrChange = $oChange;
|
||||
$ret = $this->DBInsertTracked_Internal(true);
|
||||
self::$m_oCurrChange = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
protected function DBInsertTracked_Internal($bDoNotReload = false)
|
||||
{
|
||||
if ($bDoNotReload)
|
||||
{
|
||||
$ret = parent::DBInsertNoReload();
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret = parent::DBInsert();
|
||||
}
|
||||
$this->RecordObjCreation(self::$m_oCurrChange);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function DBClone($newKey = null)
|
||||
{
|
||||
if(!self::$m_oCurrChange)
|
||||
{
|
||||
throw new CoreException("DBClone() could not be used here, please use DBCloneTracked() instead");
|
||||
}
|
||||
return $this->DBCloneTracked_Internal();
|
||||
}
|
||||
|
||||
public function DBCloneTracked(CMDBChange $oChange, $newKey = null)
|
||||
{
|
||||
self::$m_oCurrChange = $oChange;
|
||||
$this->DBCloneTracked_Internal($newKey);
|
||||
self::$m_oCurrChange = null;
|
||||
}
|
||||
|
||||
protected function DBCloneTracked_Internal($newKey = null)
|
||||
{
|
||||
$newKey = parent::DBClone($newKey);
|
||||
$oClone = MetaModel::GetObject(get_class($this), $newKey);
|
||||
|
||||
$oClone->RecordObjCreation(self::$m_oCurrChange);
|
||||
return $newKey;
|
||||
}
|
||||
|
||||
public function DBUpdate()
|
||||
{
|
||||
if(!self::$m_oCurrChange)
|
||||
{
|
||||
throw new CoreException("DBUpdate() could not be used here, please use DBUpdateTracked() instead");
|
||||
}
|
||||
return $this->DBUpdateTracked_internal();
|
||||
}
|
||||
|
||||
public function DBUpdateTracked(CMDBChange $oChange)
|
||||
{
|
||||
self::$m_oCurrChange = $oChange;
|
||||
$this->DBUpdateTracked_Internal();
|
||||
self::$m_oCurrChange = null;
|
||||
}
|
||||
|
||||
protected function DBUpdateTracked_Internal()
|
||||
{
|
||||
// Copy the changes list before the update (the list should be reset afterwards)
|
||||
$aChanges = $this->ListChanges();
|
||||
if (count($aChanges) == 0)
|
||||
{
|
||||
throw new CoreWarning("Attempting to update an unchanged object");
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the original values (will be reset to the new values when the object get written to the DB)
|
||||
$aOriginalValues = $this->m_aOrigValues;
|
||||
$ret = parent::DBUpdate();
|
||||
$this->RecordAttChanges(self::$m_oCurrChange, $aChanges, $aOriginalValues);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function DBDelete()
|
||||
{
|
||||
if(!self::$m_oCurrChange)
|
||||
{
|
||||
throw new CoreException("DBDelete() could not be used here, please use DBDeleteTracked() instead");
|
||||
}
|
||||
return $this->DBDeleteTracked_Internal();
|
||||
}
|
||||
|
||||
public function DBDeleteTracked(CMDBChange $oChange)
|
||||
{
|
||||
self::$m_oCurrChange = $oChange;
|
||||
$this->DBDeleteTracked_Internal();
|
||||
self::$m_oCurrChange = null;
|
||||
}
|
||||
|
||||
protected function DBDeleteTracked_Internal()
|
||||
{
|
||||
$prevkey = $this->GetKey();
|
||||
$ret = parent::DBDelete();
|
||||
$this->RecordObjDeletion(self::$m_oCurrChange, $prevkey);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function BulkDelete(DBObjectSearch $oFilter)
|
||||
{
|
||||
if(!self::$m_oCurrChange)
|
||||
{
|
||||
throw new CoreException("BulkDelete() could not be used here, please use BulkDeleteTracked() instead");
|
||||
}
|
||||
return $this->BulkDeleteTracked_Internal($oFilter);
|
||||
}
|
||||
|
||||
public static function BulkDeleteTracked(CMDBChange $oChange, DBObjectSearch $oFilter)
|
||||
{
|
||||
self::$m_oCurrChange = $oChange;
|
||||
$this->BulkDeleteTracked_Internal($oFilter);
|
||||
self::$m_oCurrChange = null;
|
||||
}
|
||||
|
||||
protected static function BulkDeleteTracked_Internal(DBObjectSearch $oFilter)
|
||||
{
|
||||
throw new CoreWarning("Change tracking not tested for bulk operations");
|
||||
|
||||
// Get the list of objects to delete (and record data before deleting the DB records)
|
||||
$oObjSet = new CMDBObjectSet($oFilter);
|
||||
$aObjAndKeys = array(); // array of pkey=>object
|
||||
while ($oItem = $oObjSet->Fetch())
|
||||
{
|
||||
$aObjAndKeys[$oItem->GetKey()] = $oItem;
|
||||
}
|
||||
$oObjSet->FreeResult();
|
||||
|
||||
// Delete in one single efficient query
|
||||
$ret = parent::BulkDelete($oFilter);
|
||||
// Record... in many queries !!!
|
||||
foreach($aObjAndKeys as $prevkey=>$oItem)
|
||||
{
|
||||
$oItem->RecordObjDeletion(self::$m_oCurrChange, $prevkey);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function BulkUpdate(DBObjectSearch $oFilter, array $aValues)
|
||||
{
|
||||
if(!self::$m_oCurrChange)
|
||||
{
|
||||
throw new CoreException("BulkUpdate() could not be used here, please use BulkUpdateTracked() instead");
|
||||
}
|
||||
return $this->BulkUpdateTracked_Internal($oFilter, $aValues);
|
||||
}
|
||||
|
||||
public static function BulkUpdateTracked(CMDBChange $oChange, DBObjectSearch $oFilter, array $aValues)
|
||||
{
|
||||
self::$m_oCurrChange = $oChange;
|
||||
$this->BulkUpdateTracked_Internal($oFilter, $aValues);
|
||||
self::$m_oCurrChange = null;
|
||||
}
|
||||
|
||||
protected static function BulkUpdateTracked_Internal(DBObjectSearch $oFilter, array $aValues)
|
||||
{
|
||||
// $aValues is an array of $sAttCode => $value
|
||||
|
||||
// Get the list of objects to update (and load it before doing the change)
|
||||
$oObjSet = new CMDBObjectSet($oFilter);
|
||||
$oObjSet->Load();
|
||||
|
||||
// Keep track of the previous values (will be overwritten when the objects are synchronized with the DB)
|
||||
$aOriginalValues = array();
|
||||
$oObjSet->Rewind();
|
||||
while ($oItem = $oObjSet->Fetch())
|
||||
{
|
||||
$aOriginalValues[$oItem->GetKey()] = $oItem->m_aOrigValues;
|
||||
}
|
||||
|
||||
// Update in one single efficient query
|
||||
$ret = parent::BulkUpdate($oFilter, $aValues);
|
||||
|
||||
// Record... in many queries !!!
|
||||
$oObjSet->Rewind();
|
||||
while ($oItem = $oObjSet->Fetch())
|
||||
{
|
||||
$aChangedValues = $oItem->ListChangedValues($aValues);
|
||||
$oItem->RecordAttChanges(self::$m_oCurrChange, $aChangedValues, $aOriginalValues[$oItem->GetKey()]);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* TODO: investigate how to get rid of this class that was made to workaround some language limitation... or a poor design!
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class CMDBObjectSet extends DBObjectSet
|
||||
{
|
||||
// this is the public interface (?)
|
||||
|
||||
// I have to define those constructors here... :-(
|
||||
// just to get the right object class in return.
|
||||
// I have to think again to those things: maybe it will work fine if a have a constructor define here (?)
|
||||
|
||||
static public function FromScratch($sClass)
|
||||
{
|
||||
$oFilter = new CMDBSearchFilter($sClass);
|
||||
$oRetSet = new CMDBObjectSet($oFilter); // THE ONLY DIFF IS HERE
|
||||
// NOTE: THIS DOES NOT WORK IF m_bLoaded is private...
|
||||
// BUT IT THAT CASE YOU DO NOT GET ANY ERROR !!!!!
|
||||
$oRetSet->m_bLoaded = true; // no DB load
|
||||
return $oRetSet;
|
||||
}
|
||||
|
||||
static public function FromArray($sClass, $aObjects)
|
||||
{
|
||||
$oFilter = new CMDBSearchFilter($sClass);
|
||||
$oRetSet = new CMDBObjectSet($oFilter); // THE ONLY DIFF IS HERE
|
||||
// NOTE: THIS DOES NOT WORK IF m_bLoaded is private...
|
||||
// BUT IT THAT CASE YOU DO NOT GET ANY ERROR !!!!!
|
||||
$oRetSet->m_bLoaded = true; // no DB load
|
||||
$oRetSet->AddObjectArray($aObjects);
|
||||
return $oRetSet;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: investigate how to get rid of this class that was made to workaround some language limitation... or a poor design!
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class CMDBSearchFilter extends DBObjectSearch
|
||||
{
|
||||
// this is the public interface (?)
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
498
core/cmdbsource.class.inc.php
Normal file
498
core/cmdbsource.class.inc.php
Normal file
@@ -0,0 +1,498 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CMDBSource
|
||||
* database access wrapper
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
require_once('MyHelpers.class.inc.php');
|
||||
|
||||
class MySQLException extends CoreException
|
||||
{
|
||||
public function __construct($sIssue, $aContext)
|
||||
{
|
||||
$aContext['mysql_error'] = mysql_error();
|
||||
$aContext['mysql_errno'] = mysql_errno();
|
||||
parent::__construct($sIssue, $aContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CMDBSource
|
||||
{
|
||||
protected static $m_sDBHost;
|
||||
protected static $m_sDBUser;
|
||||
protected static $m_sDBPwd;
|
||||
protected static $m_sDBName;
|
||||
protected static $m_resDBLink;
|
||||
|
||||
public static function Init($sServer, $sUser, $sPwd, $sSource = '')
|
||||
{
|
||||
self::$m_sDBHost = $sServer;
|
||||
self::$m_sDBUser = $sUser;
|
||||
self::$m_sDBPwd = $sPwd;
|
||||
self::$m_sDBName = $sSource;
|
||||
if (!self::$m_resDBLink = @mysql_pconnect($sServer, $sUser, $sPwd))
|
||||
{
|
||||
throw new MySQLException('Could not connect to the DB server', array('host'=>$sServer, 'user'=>$sUser));
|
||||
}
|
||||
if (!empty($sSource))
|
||||
{
|
||||
if (!mysql_select_db($sSource, self::$m_resDBLink))
|
||||
{
|
||||
throw new MySQLException('Could not select DB', array('host'=>$sServer, 'user'=>$sUser, 'db_name'=>$sSource));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function ListDB()
|
||||
{
|
||||
$aDBs = self::QueryToCol('SHOW DATABASES', 'Database');
|
||||
// Show Database does return the DB names in lower case
|
||||
return $aDBs;
|
||||
}
|
||||
|
||||
public static function IsDB($sSource)
|
||||
{
|
||||
try
|
||||
{
|
||||
$aDBs = self::ListDB();
|
||||
foreach($aDBs as $sDBName)
|
||||
{
|
||||
// perform a case insensitive test because on Windows the table names become lowercase :-(
|
||||
if (strtolower($sDBName) == strtolower($sSource)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
// In case we don't have rights to enumerate the databases
|
||||
// Let's try to connect directly
|
||||
return @mysql_select_db($sSource, self::$m_resDBLink);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function GetDBVersion()
|
||||
{
|
||||
$aVersions = self::QueryToCol('SELECT Version() as version', 'version');
|
||||
return $aVersions[0];
|
||||
}
|
||||
|
||||
public static function SelectDB($sSource)
|
||||
{
|
||||
if (!mysql_select_db($sSource, self::$m_resDBLink))
|
||||
{
|
||||
throw new MySQLException('Could not select DB', array('db_name'=>$sSource));
|
||||
}
|
||||
self::$m_sDBName = $sSource;
|
||||
}
|
||||
|
||||
public static function CreateDB($sSource)
|
||||
{
|
||||
self::Query("CREATE DATABASE `$sSource` CHARACTER SET utf8 COLLATE utf8_unicode_ci");
|
||||
self::SelectDB($sSource);
|
||||
}
|
||||
|
||||
public static function DropDB($sDBToDrop = '')
|
||||
{
|
||||
if (empty($sDBToDrop))
|
||||
{
|
||||
$sDBToDrop = self::$m_sDBName;
|
||||
}
|
||||
self::Query("DROP DATABASE `$sDBToDrop`");
|
||||
if ($sDBToDrop == self::$m_sDBName)
|
||||
{
|
||||
self::$m_sDBName = '';
|
||||
}
|
||||
}
|
||||
|
||||
public static function CreateTable($sQuery)
|
||||
{
|
||||
$res = self::Query($sQuery);
|
||||
self::_TablesInfoCacheReset(); // reset the table info cache!
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function DropTable($sTable)
|
||||
{
|
||||
$res = self::Query("DROP TABLE `$sTable`");
|
||||
self::_TablesInfoCacheReset(true); // reset the table info cache!
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function DBHost() {return self::$m_sDBHost;}
|
||||
public static function DBUser() {return self::$m_sDBUser;}
|
||||
public static function DBPwd() {return self::$m_sDBPwd;}
|
||||
public static function DBName() {return self::$m_sDBName;}
|
||||
|
||||
public static function Quote($value, $bAlways = false, $cQuoteStyle = "'")
|
||||
{
|
||||
// Quote variable and protect against SQL injection attacks
|
||||
// Code found in the PHP documentation: quote_smart($value)
|
||||
|
||||
// bAlways should be set to true when the purpose is to create a IN clause,
|
||||
// otherwise and if there is a mix of strings and numbers, the clause
|
||||
// would always be false
|
||||
|
||||
if (is_array($value))
|
||||
{
|
||||
$aRes = array();
|
||||
foreach ($value as $key => $itemvalue)
|
||||
{
|
||||
$aRes[$key] = self::Quote($itemvalue, $bAlways, $cQuoteStyle);
|
||||
}
|
||||
return $aRes;
|
||||
}
|
||||
|
||||
// Stripslashes
|
||||
if (get_magic_quotes_gpc())
|
||||
{
|
||||
$value = stripslashes($value);
|
||||
}
|
||||
// Quote if not a number or a numeric string
|
||||
if ($bAlways || !is_numeric($value))
|
||||
{
|
||||
$value = $cQuoteStyle . mysql_real_escape_string($value, self::$m_resDBLink) . $cQuoteStyle;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public static function Query($sSQLQuery)
|
||||
{
|
||||
// Add info into the query as a comment, for easier error tracking
|
||||
// disabled until we need it really!
|
||||
//
|
||||
//$aTraceInf['file'] = __FILE__;
|
||||
// $sSQLQuery .= MyHelpers::MakeSQLComment($aTraceInf);
|
||||
|
||||
$mu_t1 = MyHelpers::getmicrotime();
|
||||
$result = mysql_query($sSQLQuery, self::$m_resDBLink);
|
||||
if (!$result)
|
||||
{
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSQLQuery));
|
||||
}
|
||||
$mu_t2 = MyHelpers::getmicrotime();
|
||||
// #@# todo - query_trace($sSQLQuery, $mu_t2 - $mu_t1);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function GetNextInsertId($sTable)
|
||||
{
|
||||
$sSQL = "SHOW TABLE STATUS LIKE '$sTable'";
|
||||
$result = self::Query($sSQL);
|
||||
$aRow = mysql_fetch_assoc($result);
|
||||
$iNextInsertId = $aRow['Auto_increment'];
|
||||
return $iNextInsertId;
|
||||
}
|
||||
|
||||
public static function GetInsertId()
|
||||
{
|
||||
return mysql_insert_id(self::$m_resDBLink);
|
||||
}
|
||||
public static function InsertInto($sSQLQuery)
|
||||
{
|
||||
if (self::Query($sSQLQuery))
|
||||
{
|
||||
return self::GetInsertId();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function QueryToArray($sSql)
|
||||
{
|
||||
$aData = array();
|
||||
$result = mysql_query($sSql, self::$m_resDBLink);
|
||||
if (!$result)
|
||||
{
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql));
|
||||
}
|
||||
while ($aRow = mysql_fetch_array($result, MYSQL_BOTH))
|
||||
{
|
||||
$aData[] = $aRow;
|
||||
}
|
||||
mysql_free_result($result);
|
||||
return $aData;
|
||||
}
|
||||
|
||||
public static function QueryToCol($sSql, $col)
|
||||
{
|
||||
$aColumn = array();
|
||||
$aData = self::QueryToArray($sSql);
|
||||
foreach($aData as $aRow)
|
||||
{
|
||||
@$aColumn[] = $aRow[$col];
|
||||
}
|
||||
return $aColumn;
|
||||
}
|
||||
|
||||
public static function ExplainQuery($sSql)
|
||||
{
|
||||
$aData = array();
|
||||
$result = mysql_query("EXPLAIN $sSql", self::$m_resDBLink);
|
||||
if (!$result)
|
||||
{
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql));
|
||||
}
|
||||
|
||||
$aNames = array();
|
||||
for ($i = 0; $i < mysql_num_fields($result) ; $i++)
|
||||
{
|
||||
$meta = mysql_fetch_field($result, $i);
|
||||
if (!$meta)
|
||||
{
|
||||
throw new MySQLException('mysql_fetch_field: No information available', array('query'=>$sSql, 'i'=>$i));
|
||||
}
|
||||
else
|
||||
{
|
||||
$aNames[] = $meta->name;
|
||||
}
|
||||
}
|
||||
|
||||
$aData[] = $aNames;
|
||||
while ($aRow = mysql_fetch_array($result, MYSQL_ASSOC))
|
||||
{
|
||||
$aData[] = $aRow;
|
||||
}
|
||||
mysql_free_result($result);
|
||||
return $aData;
|
||||
}
|
||||
|
||||
public static function TestQuery($sSql)
|
||||
{
|
||||
$result = mysql_query("EXPLAIN $sSql", self::$m_resDBLink);
|
||||
if (!$result)
|
||||
{
|
||||
return mysql_error();
|
||||
}
|
||||
|
||||
mysql_free_result($result);
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function NbRows($result)
|
||||
{
|
||||
return mysql_num_rows($result);
|
||||
}
|
||||
|
||||
public static function FetchArray($result)
|
||||
{
|
||||
return mysql_fetch_array($result, MYSQL_ASSOC);
|
||||
}
|
||||
|
||||
public static function Seek($result, $iRow)
|
||||
{
|
||||
return mysql_data_seek($result, $iRow);
|
||||
}
|
||||
|
||||
public static function FreeResult($result)
|
||||
{
|
||||
return mysql_free_result($result);
|
||||
}
|
||||
|
||||
public static function IsTable($sTable)
|
||||
{
|
||||
$aTableInfo = self::GetTableInfo($sTable);
|
||||
return (!empty($aTableInfo));
|
||||
}
|
||||
|
||||
public static function IsKey($sTable, $iKey)
|
||||
{
|
||||
$aTableInfo = self::GetTableInfo($sTable);
|
||||
if (empty($aTableInfo)) return false;
|
||||
if (!array_key_exists($iKey, $aTableInfo["Fields"])) return false;
|
||||
$aFieldData = $aTableInfo["Fields"][$iKey];
|
||||
if (!array_key_exists("Key", $aFieldData)) return false;
|
||||
return ($aFieldData["Key"] == "PRI");
|
||||
}
|
||||
|
||||
public static function IsAutoIncrement($sTable, $sField)
|
||||
{
|
||||
$aTableInfo = self::GetTableInfo($sTable);
|
||||
if (empty($aTableInfo)) return false;
|
||||
if (!array_key_exists($sField, $aTableInfo["Fields"])) return false;
|
||||
$aFieldData = $aTableInfo["Fields"][$sField];
|
||||
if (!array_key_exists("Extra", $aFieldData)) return false;
|
||||
//MyHelpers::debug_breakpoint($aFieldData);
|
||||
return (strstr($aFieldData["Extra"], "auto_increment"));
|
||||
}
|
||||
|
||||
public static function IsField($sTable, $sField)
|
||||
{
|
||||
$aTableInfo = self::GetTableInfo($sTable);
|
||||
if (empty($aTableInfo)) return false;
|
||||
if (!array_key_exists($sField, $aTableInfo["Fields"])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function IsNullAllowed($sTable, $sField)
|
||||
{
|
||||
$aTableInfo = self::GetTableInfo($sTable);
|
||||
if (empty($aTableInfo)) return false;
|
||||
if (!array_key_exists($sField, $aTableInfo["Fields"])) return false;
|
||||
$aFieldData = $aTableInfo["Fields"][$sField];
|
||||
return (strtolower($aFieldData["Null"]) == "yes");
|
||||
}
|
||||
|
||||
public static function GetFieldType($sTable, $sField)
|
||||
{
|
||||
$aTableInfo = self::GetTableInfo($sTable);
|
||||
if (empty($aTableInfo)) return false;
|
||||
if (!array_key_exists($sField, $aTableInfo["Fields"])) return false;
|
||||
$aFieldData = $aTableInfo["Fields"][$sField];
|
||||
return ($aFieldData["Type"]);
|
||||
}
|
||||
|
||||
public static function HasIndex($sTable, $sField)
|
||||
{
|
||||
$aTableInfo = self::GetTableInfo($sTable);
|
||||
if (empty($aTableInfo)) return false;
|
||||
if (!array_key_exists($sField, $aTableInfo["Fields"])) return false;
|
||||
$aFieldData = $aTableInfo["Fields"][$sField];
|
||||
// $aFieldData could be 'PRI' for the primary key, or 'MUL', or ?
|
||||
return (strlen($aFieldData["Key"]) > 0);
|
||||
}
|
||||
|
||||
// Returns an array of (fieldname => array of field info)
|
||||
public static function GetTableFieldsList($sTable)
|
||||
{
|
||||
assert(!empty($sTable));
|
||||
|
||||
$aTableInfo = self::GetTableInfo($sTable);
|
||||
if (empty($aTableInfo)) return array(); // #@# or an error ?
|
||||
|
||||
return array_keys($aTableInfo["Fields"]);
|
||||
}
|
||||
|
||||
// Cache the information about existing tables, and their fields
|
||||
private static $m_aTablesInfo = array();
|
||||
private static function _TablesInfoCacheReset()
|
||||
{
|
||||
self::$m_aTablesInfo = array();
|
||||
}
|
||||
private static function _TableInfoCacheInit($sTableName)
|
||||
{
|
||||
if (isset(self::$m_aTablesInfo[strtolower($sTableName)])
|
||||
&& (self::$m_aTablesInfo[strtolower($sTableName)] != null)) return;
|
||||
|
||||
try
|
||||
{
|
||||
// Check if the table exists
|
||||
$aFields = self::QueryToArray("SHOW COLUMNS FROM `$sTableName`");
|
||||
// Note: without backticks, you get an error with some table names (e.g. "group")
|
||||
foreach ($aFields as $aFieldData)
|
||||
{
|
||||
$sFieldName = $aFieldData["Field"];
|
||||
self::$m_aTablesInfo[strtolower($sTableName)]["Fields"][$sFieldName] =
|
||||
array
|
||||
(
|
||||
"Name"=>$aFieldData["Field"],
|
||||
"Type"=>$aFieldData["Type"],
|
||||
"Null"=>$aFieldData["Null"],
|
||||
"Key"=>$aFieldData["Key"],
|
||||
"Default"=>$aFieldData["Default"],
|
||||
"Extra"=>$aFieldData["Extra"]
|
||||
);
|
||||
}
|
||||
}
|
||||
catch(MySQLException $e)
|
||||
{
|
||||
// Table does not exist
|
||||
self::$m_aTablesInfo[strtolower($sTableName)] = null;
|
||||
}
|
||||
}
|
||||
//public static function EnumTables()
|
||||
//{
|
||||
// self::_TablesInfoCacheInit();
|
||||
// return array_keys(self::$m_aTablesInfo);
|
||||
//}
|
||||
public static function GetTableInfo($sTable)
|
||||
{
|
||||
self::_TableInfoCacheInit($sTable);
|
||||
|
||||
// perform a case insensitive match because on Windows the table names become lowercase :-(
|
||||
//foreach(self::$m_aTablesInfo as $sTableName => $aInfo)
|
||||
//{
|
||||
// if (strtolower($sTableName) == strtolower($sTable))
|
||||
// {
|
||||
// return $aInfo;
|
||||
// }
|
||||
//}
|
||||
return self::$m_aTablesInfo[strtolower($sTable)];
|
||||
//return null;
|
||||
}
|
||||
|
||||
public static function DumpTable($sTable)
|
||||
{
|
||||
$sSql = "SELECT * FROM `$sTable`";
|
||||
$result = mysql_query($sSql, self::$m_resDBLink);
|
||||
if (!$result)
|
||||
{
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql));
|
||||
}
|
||||
|
||||
$aRows = array();
|
||||
while ($aRow = mysql_fetch_array($result, MYSQL_ASSOC))
|
||||
{
|
||||
$aRows[] = $aRow;
|
||||
}
|
||||
mysql_free_result($result);
|
||||
return $aRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified server variable
|
||||
* @param string $sVarName Name of the server variable
|
||||
* @return mixed Current value of the variable
|
||||
*/
|
||||
public static function GetServerVariable($sVarName)
|
||||
{
|
||||
$result = '';
|
||||
$sSql = "SELECT @@$sVarName as theVar";
|
||||
$aRows = self::QueryToArray($sSql);
|
||||
if (count($aRows) > 0)
|
||||
{
|
||||
$result = $aRows[0]['theVar'];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the privileges of the current user
|
||||
* @return string privileges in a raw format
|
||||
*/
|
||||
public static function GetRawPrivileges()
|
||||
{
|
||||
try
|
||||
{
|
||||
$result = self::Query('SHOW GRANTS'); // [ FOR CURRENT_USER()]
|
||||
}
|
||||
catch(MySQLException $e)
|
||||
{
|
||||
return "Current user not allowed to see his own privileges (could not access to the database 'mysql' - $iCode)";
|
||||
}
|
||||
|
||||
$aRes = array();
|
||||
while ($aRow = mysql_fetch_array($result, MYSQL_NUM))
|
||||
{
|
||||
// so far, only one column...
|
||||
$aRes[] = implode('/', $aRow);
|
||||
}
|
||||
mysql_free_result($result);
|
||||
// so far, only one line...
|
||||
return implode(', ', $aRes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
357
core/config.class.inc.php
Normal file
357
core/config.class.inc.php
Normal file
@@ -0,0 +1,357 @@
|
||||
<?php
|
||||
require_once('coreexception.class.inc.php');
|
||||
/**
|
||||
* Config
|
||||
* configuration data
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class ConfigException extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
define ('DEFAULT_MIN_DISPLAY_LIMIT', 10);
|
||||
define ('DEFAULT_MAX_DISPLAY_LIMIT', 15);
|
||||
define ('DEFAULT_STANDARD_RELOAD_INTERVAL', 5*60);
|
||||
define ('DEFAULT_FAST_RELOAD_INTERVAL', 1*60);
|
||||
|
||||
class Config
|
||||
{
|
||||
//protected $m_bIsLoaded = false;
|
||||
protected $m_sFile = '';
|
||||
|
||||
protected $m_aAppModules;
|
||||
protected $m_aDataModels;
|
||||
protected $m_aAddons;
|
||||
|
||||
protected $m_sDBHost;
|
||||
protected $m_sDBUser;
|
||||
protected $m_sDBPwd;
|
||||
protected $m_sDBName;
|
||||
protected $m_sDBSubname;
|
||||
|
||||
/**
|
||||
* @var integer Number of elements to be displayed when there are more than m_iMaxDisplayLimit elements
|
||||
*/
|
||||
protected $m_iMinDisplayLimit;
|
||||
/**
|
||||
* @var integer Max number of elements before truncating the display
|
||||
*/
|
||||
protected $m_iMaxDisplayLimit;
|
||||
|
||||
/**
|
||||
* @var integer Number of seconds between two reloads of the display (standard)
|
||||
*/
|
||||
protected $m_iStandardReloadInterval;
|
||||
/**
|
||||
* @var integer Number of seconds between two reloads of the display (fast)
|
||||
*/
|
||||
protected $m_iFastReloadInterval;
|
||||
|
||||
public function __construct($sConfigFile, $bLoadConfig = true)
|
||||
{
|
||||
$this->m_sFile = $sConfigFile;
|
||||
$this->m_aAppModules = array();
|
||||
$this->m_aDataModels = array();
|
||||
$this->m_aAddons = array();
|
||||
|
||||
$this->m_sDBHost = '';
|
||||
$this->m_sDBUser = '';
|
||||
$this->m_sDBPwd = '';
|
||||
$this->m_sDBName = '';
|
||||
$this->m_sDBSubname = '';
|
||||
$this->m_iMinDisplayLimit = DEFAULT_MIN_DISPLAY_LIMIT;
|
||||
$this->m_iMaxDisplayLimit = DEFAULT_MAX_DISPLAY_LIMIT;
|
||||
$this->m_iStandardReloadInterval = DEFAULT_STANDARD_RELOAD_INTERVAL;
|
||||
$this->m_iFastReloadInterval = DEFAULT_FAST_RELOAD_INTERVAL;
|
||||
if ($bLoadConfig)
|
||||
{
|
||||
$this->Load($sConfigFile);
|
||||
$this->Verify();
|
||||
}
|
||||
}
|
||||
|
||||
protected function CheckFile($sPurpose, $sFileName)
|
||||
{
|
||||
if (!file_exists($sFileName))
|
||||
{
|
||||
throw new ConfigException("Could not find $sPurpose file", array('file' => $sFileName));
|
||||
}
|
||||
}
|
||||
|
||||
protected function Load($sConfigFile)
|
||||
{
|
||||
$this->CheckFile('configuration', $sConfigFile);
|
||||
|
||||
$sConfigCode = trim(file_get_contents($sConfigFile));
|
||||
|
||||
// This does not work on several lines
|
||||
// preg_match('/^<\\?php(.*)\\?'.'>$/', $sConfigCode, $aMatches)...
|
||||
// So, I've implemented a solution suggested in the PHP doc (search for phpWrapper)
|
||||
try
|
||||
{
|
||||
ob_start();
|
||||
eval('?'.'>'.trim($sConfigCode));
|
||||
$sNoise = trim(ob_get_contents());
|
||||
ob_end_clean();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
// well, never reach in case of parsing error :-(
|
||||
// will be improved in PHP 6 ?
|
||||
throw new ConfigException('Error in configuration file', array('file' => $sConfigFile, 'error' => $e->getMessage()));
|
||||
}
|
||||
if (strlen($sNoise) > 0)
|
||||
{
|
||||
// Note: sNoise is an html output, but so far it was ok for me (e.g. showing the entire call stack)
|
||||
throw new ConfigException('Syntax error in configuration file', array('file' => $sConfigFile, 'error' => '<tt>'.htmlentities($sNoise).'</tt>'));
|
||||
}
|
||||
|
||||
if (!isset($MySettings) || !is_array($MySettings))
|
||||
{
|
||||
throw new ConfigException('Missing array in configuration file', array('file' => $sConfigFile, 'expected' => '$MySettings'));
|
||||
}
|
||||
if (!isset($MyModules) || !is_array($MyModules))
|
||||
{
|
||||
throw new ConfigException('Missing item in configuration file', array('file' => $sConfigFile, 'expected' => '$MyModules'));
|
||||
}
|
||||
if (!array_key_exists('application', $MyModules))
|
||||
{
|
||||
throw new ConfigException('Missing item in configuration file', array('file' => $sConfigFile, 'expected' => '$MyModules[\'application\']'));
|
||||
}
|
||||
if (!array_key_exists('business', $MyModules))
|
||||
{
|
||||
throw new ConfigException('Missing item in configuration file', array('file' => $sConfigFile, 'expected' => '$MyModules[\'business\']'));
|
||||
}
|
||||
if (!array_key_exists('addons', $MyModules))
|
||||
{
|
||||
throw new ConfigException('Missing item in configuration file', array('file' => $sConfigFile, 'expected' => '$MyModules[\'addons\']'));
|
||||
}
|
||||
if (!array_key_exists('user rights', $MyModules['addons']))
|
||||
{
|
||||
$MyModules['addons']['user rights'] = '../addons/userrights/userrightsnull.class.inc.php';
|
||||
}
|
||||
$this->m_aAppModules = $MyModules['application'];
|
||||
$this->m_aDataModels = $MyModules['business'];
|
||||
$this->m_aAddons = $MyModules['addons'];
|
||||
|
||||
$this->m_sDBHost = trim($MySettings['db_host']);
|
||||
$this->m_sDBUser = trim($MySettings['db_user']);
|
||||
$this->m_sDBPwd = trim($MySettings['db_pwd']);
|
||||
$this->m_sDBName = trim($MySettings['db_name']);
|
||||
$this->m_sDBSubname = trim($MySettings['db_subname']);
|
||||
|
||||
$this->m_iMinDisplayLimit = isset($MySettings['min_display_limit']) ? trim($MySettings['min_display_limit']) : DEFAULT_MIN_DISPLAY_LIMIT;
|
||||
$this->m_iMaxDisplayLimit = isset($MySettings['max_display_limit']) ? trim($MySettings['max_display_limit']) : DEFAULT_MAX_DISPLAY_LIMIT;
|
||||
$this->m_iStandardReloadInterval = isset($MySettings['standard_reload_interval']) ? trim($MySettings['standard_reload_interval']) : DEFAULT_STANDARD_RELOAD_INTERVAL;
|
||||
$this->m_iFastReloadInterval = isset($MySettings['fast_reload_interval']) ? trim($MySettings['fast_reload_interval']) : DEFAULT_FAST_RELOAD_INTERVAL;
|
||||
}
|
||||
|
||||
protected function Verify()
|
||||
{
|
||||
foreach ($this->m_aAppModules as $sModule => $sToInclude)
|
||||
{
|
||||
$this->CheckFile('application module', $sToInclude);
|
||||
}
|
||||
foreach ($this->m_aDataModels as $sModule => $sToInclude)
|
||||
{
|
||||
$this->CheckFile('business model', $sToInclude);
|
||||
}
|
||||
foreach ($this->m_aAddons as $sModule => $sToInclude)
|
||||
{
|
||||
$this->CheckFile('addon module', $sToInclude);
|
||||
}
|
||||
}
|
||||
|
||||
public function GetAppModules()
|
||||
{
|
||||
return $this->m_aAppModules;
|
||||
}
|
||||
|
||||
public function GetDataModels()
|
||||
{
|
||||
return $this->m_aDataModels;
|
||||
}
|
||||
|
||||
public function GetAddons()
|
||||
{
|
||||
return $this->m_aAddons;
|
||||
}
|
||||
|
||||
public function GetDBHost()
|
||||
{
|
||||
return $this->m_sDBHost;
|
||||
}
|
||||
|
||||
public function GetDBName()
|
||||
{
|
||||
return $this->m_sDBName;
|
||||
}
|
||||
|
||||
public function GetDBSubname()
|
||||
{
|
||||
return $this->m_sDBSubname;
|
||||
}
|
||||
|
||||
public function GetDBUser()
|
||||
{
|
||||
return $this->m_sDBUser;
|
||||
}
|
||||
|
||||
public function GetDBPwd()
|
||||
{
|
||||
return $this->m_sDBPwd;
|
||||
}
|
||||
|
||||
public function GetMinDisplayLimit()
|
||||
{
|
||||
return $this->m_iMinDisplayLimit;
|
||||
}
|
||||
|
||||
public function GetMaxDisplayLimit()
|
||||
{
|
||||
return $this->m_iMaxDisplayLimit;
|
||||
}
|
||||
|
||||
public function GetStandardReloadInterval()
|
||||
{
|
||||
return $this->m_iStandardReloadInterval;
|
||||
}
|
||||
|
||||
public function GetFastReloadInterval()
|
||||
{
|
||||
return $this->m_iFastReloadInterval;
|
||||
}
|
||||
|
||||
public function SetDBHost($sDBHost)
|
||||
{
|
||||
$this->m_sDBHost = $sDBHost;
|
||||
}
|
||||
|
||||
public function SetDBName($sDBName)
|
||||
{
|
||||
$this->m_sDBName = $sDBName;
|
||||
}
|
||||
|
||||
public function SetDBSubname($sDBSubName)
|
||||
{
|
||||
$this->m_sDBSubname = $sDBSubName;
|
||||
}
|
||||
|
||||
public function SetDBUser($sUser)
|
||||
{
|
||||
$this->m_sDBUser = $sUser;
|
||||
}
|
||||
|
||||
public function SetDBPwd($sPwd)
|
||||
{
|
||||
$this->m_sDBPwd = $sPwd;
|
||||
}
|
||||
|
||||
public function SetMinDisplayLimit($iMinDisplayLimit)
|
||||
{
|
||||
$this->m_iMinDisplayLimit = $iMinDisplayLimit;
|
||||
}
|
||||
|
||||
public function SetMaxDisplayLimit($iMaxDisplayLimit)
|
||||
{
|
||||
$this->m_iMaxDisplayLimit = $iMaxDisplayLimit;
|
||||
}
|
||||
|
||||
public function SetStandardReloadInterval($iStandardReloadInterval)
|
||||
{
|
||||
$this->m_iStandardReloadInterval = $iStandardReloadInterval;
|
||||
}
|
||||
|
||||
public function SetFastReloadInterval($iFastReloadInterval)
|
||||
{
|
||||
$this->m_iFastReloadInterval = $iFastReloadInterval;
|
||||
}
|
||||
|
||||
public function FileIsWritable()
|
||||
{
|
||||
return is_writable($this->m_sFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the configuration to a file (php format) that can be reloaded later
|
||||
* By default write to the same file that was specified when constructing the object
|
||||
* @param $sFileName string Name of the file to write to (emtpy to write to the same file)
|
||||
* @return boolean True otherwise throws an Exception
|
||||
*/
|
||||
public function WriteToFile($sFileName = '')
|
||||
{
|
||||
if (empty($sFileName))
|
||||
{
|
||||
$sFileName = $this->m_sFile;
|
||||
}
|
||||
$hFile = @fopen($sFileName, 'w');
|
||||
if ($hFile !== false)
|
||||
{
|
||||
fwrite($hFile, "<?php\n");
|
||||
fwrite($hFile, "\n/**\n");
|
||||
fwrite($hFile, " *\n");
|
||||
fwrite($hFile, " * phpMyORM configuration file, generated by the iTop configuration wizard\n");
|
||||
fwrite($hFile, " *\n");
|
||||
fwrite($hFile, " * The file is used in MetaModel::LoadConfig() which does all the necessary initialization job\n");
|
||||
fwrite($hFile, " *\n");
|
||||
fwrite($hFile, " */\n");
|
||||
fwrite($hFile, "\n");
|
||||
|
||||
fwrite($hFile, "\$MySettings = array(\n");
|
||||
fwrite($hFile, "\t'db_host' => '{$this->m_sDBHost}',\n");
|
||||
fwrite($hFile, "\t'db_user' => '{$this->m_sDBUser}',\n");
|
||||
fwrite($hFile, "\t'db_pwd' => '".addslashes($this->m_sDBPwd)."',\n");
|
||||
fwrite($hFile, "\t'db_name' => '{$this->m_sDBName}',\n");
|
||||
fwrite($hFile, "\t'db_subname' => '{$this->m_sDBSubname}',\n");
|
||||
fwrite($hFile, "\n");
|
||||
fwrite($hFile, "\t'min_display_limit' => {$this->m_iMinDisplayLimit},\n");
|
||||
fwrite($hFile, "\t'max_display_limit' => {$this->m_iMaxDisplayLimit},\n");
|
||||
fwrite($hFile, "\t'standard_reload_interval' => {$this->m_iStandardReloadInterval},\n");
|
||||
fwrite($hFile, "\t'fast_reload_interval' => {$this->m_iFastReloadInterval},\n");
|
||||
fwrite($hFile, ");\n");
|
||||
|
||||
fwrite($hFile, "\n/**\n");
|
||||
fwrite($hFile, " *\n");
|
||||
fwrite($hFile, " * Data model modules to be loaded. Names should be specified as absolute paths\n");
|
||||
fwrite($hFile, " *\n");
|
||||
fwrite($hFile, " */\n");
|
||||
fwrite($hFile, "\$MyModules = array(\n");
|
||||
fwrite($hFile, "\t'application' => array (\n");
|
||||
fwrite($hFile, "\t\t'../application/menunode.class.inc.php',\n");
|
||||
fwrite($hFile, "\t\t'../application/audit.rule.class.inc.php',\n");
|
||||
// Romain - That's dirty, because those 3 classes are in fact part of the core
|
||||
// but I needed those classes to be derived from cmdbAbstractObject
|
||||
// (to be managed via the GUI) and this class in not really known from
|
||||
// the core, PLUS I needed the includes to be there also for the setup
|
||||
// to create the tables.
|
||||
fwrite($hFile, "\t\t'../core/event.class.inc.php',\n");
|
||||
fwrite($hFile, "\t\t'../core/action.class.inc.php',\n");
|
||||
fwrite($hFile, "\t\t'../core/trigger.class.inc.php',\n");
|
||||
fwrite($hFile, "\t\t// to be continued...\n");
|
||||
fwrite($hFile, "\t),\n");
|
||||
fwrite($hFile, "\t'business' => array (\n");
|
||||
fwrite($hFile, "\t\t'../business/itop.business.class.inc.php'\n");
|
||||
fwrite($hFile, "\t\t// to be continued...\n");
|
||||
fwrite($hFile, "\t),\n");
|
||||
fwrite($hFile, "\t'addons' => array (\n");
|
||||
fwrite($hFile, "\t\t'user rights' => '../addons/userrights/userrightsprofile.class.inc.php',\n");
|
||||
fwrite($hFile, "\t\t// other modules to come later\n");
|
||||
fwrite($hFile, "\t)\n");
|
||||
fwrite($hFile, ");\n");
|
||||
fwrite($hFile, '?'.'>'); // Avoid perturbing the syntax highlighting !
|
||||
return fclose($hFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ConfigException("Could not write to configuration file", array('file' => $sFileName));
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
73
core/coreexception.class.inc.php
Normal file
73
core/coreexception.class.inc.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
|
||||
class SecurityException extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
class CoreException extends Exception
|
||||
{
|
||||
public function __construct($sIssue, $aContextData = null, $sImpact = '')
|
||||
{
|
||||
$this->m_sIssue = $sIssue;
|
||||
$this->m_sImpact = $sImpact;
|
||||
$this->m_aContextData = $aContextData ? $aContextData : array();
|
||||
|
||||
$sMessage = $sIssue;
|
||||
if (!empty($sImpact)) $sMessage .= "($sImpact)";
|
||||
if (count($this->m_aContextData) > 0)
|
||||
{
|
||||
$sMessage .= ": ";
|
||||
$aContextItems = array();
|
||||
foreach($this->m_aContextData as $sKey => $value)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
$aPairs = array();
|
||||
foreach($value as $key => $val)
|
||||
{
|
||||
if (is_array($val))
|
||||
{
|
||||
$aPairs[] = $key.'=>('.implode(', ', $val).')';
|
||||
}
|
||||
else
|
||||
{
|
||||
$aPairs[] = $key.'=>'.$val;
|
||||
}
|
||||
}
|
||||
$sValue = '{'.implode('; ', $aPairs).'}';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sValue = $value;
|
||||
}
|
||||
$aContextItems[] = "$sKey = $sValue";
|
||||
}
|
||||
$sMessage .= implode(', ', $aContextItems);
|
||||
}
|
||||
parent::__construct($sMessage, 0);
|
||||
}
|
||||
|
||||
public function getHtmlDesc($sHighlightHtmlBegin = '<b>', $sHighlightHtmlEnd = '</b>')
|
||||
{
|
||||
return $this->getMessage();
|
||||
}
|
||||
|
||||
public function getTraceAsHtml()
|
||||
{
|
||||
$aBackTrace = $this->getTrace();
|
||||
return MyHelpers::get_callstack_html(0, $this->getTrace());
|
||||
// return "<pre>\n".$this->getTraceAsString()."</pre>\n";
|
||||
}
|
||||
|
||||
public function addInfo($sKey, $value)
|
||||
{
|
||||
$this->m_aContextData[$sKey] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
class CoreWarning extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
?>
|
||||
192
core/csvparser.class.inc.php
Normal file
192
core/csvparser.class.inc.php
Normal file
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CSVParser
|
||||
* CSV interpreter helper, optionaly tries to guess column mapping and the separator, check the consistency
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
class CSVParserException extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* CSVParser
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class CSVParser
|
||||
{
|
||||
private $m_sCSVData;
|
||||
private $m_sSep;
|
||||
private $m_iSkip;
|
||||
|
||||
public function __construct($sTxt)
|
||||
{
|
||||
$this->m_sCSVData = $sTxt;
|
||||
}
|
||||
|
||||
public function SetSeparator($sSep)
|
||||
{
|
||||
$this->m_sSep = $sSep;
|
||||
}
|
||||
public function GetSeparator()
|
||||
{
|
||||
return $this->m_sSep;
|
||||
}
|
||||
|
||||
public function SetSkipLines($iSkip)
|
||||
{
|
||||
$this->m_iSkip = $iSkip;
|
||||
}
|
||||
public function GetSkipLines()
|
||||
{
|
||||
return $this->m_iSkip;
|
||||
}
|
||||
|
||||
public function GuessSeparator()
|
||||
{
|
||||
// Note: skip the first line anyway
|
||||
|
||||
$aKnownSeps = array(';', ',', "\t"); // Use double quote for special chars!!!
|
||||
$aStatsBySeparator = array();
|
||||
foreach ($aKnownSeps as $sSep)
|
||||
{
|
||||
$aStatsBySeparator[$sSep] = array();
|
||||
}
|
||||
|
||||
foreach(explode("\n", $this->m_sCSVData) as $sLine)
|
||||
{
|
||||
$sLine = trim($sLine);
|
||||
if (substr($sLine, 0, 1) == '#') continue;
|
||||
if (empty($sLine)) continue;
|
||||
|
||||
$aLineCharsCount = count_chars($sLine, 0);
|
||||
foreach ($aKnownSeps as $sSep)
|
||||
{
|
||||
$aStatsBySeparator[$sSep][] = $aLineCharsCount[ord($sSep)];
|
||||
}
|
||||
}
|
||||
|
||||
// Default to ','
|
||||
$this->SetSeparator(",");
|
||||
|
||||
foreach ($aKnownSeps as $sSep)
|
||||
{
|
||||
// Note: this function is NOT available :-(
|
||||
// stats_variance($aStatsBySeparator[$sSep]);
|
||||
$iMin = min($aStatsBySeparator[$sSep]);
|
||||
$iMax = max($aStatsBySeparator[$sSep]);
|
||||
if (($iMin == $iMax) && ($iMax > 0))
|
||||
{
|
||||
$this->SetSeparator($sSep);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $this->GetSeparator();
|
||||
}
|
||||
|
||||
public function GuessSkipLines()
|
||||
{
|
||||
// Take the FIRST -valuable- LINE ONLY
|
||||
// If there is a number, then for sure this is not a header line
|
||||
// Otherwise, we may consider that there is one line to skip
|
||||
foreach(explode("\n", $this->m_sCSVData) as $sLine)
|
||||
{
|
||||
$sLine = trim($sLine);
|
||||
if (substr($sLine, 0, 1) == '#') continue;
|
||||
if (empty($sLine)) continue;
|
||||
|
||||
foreach (explode($this->m_sSep, $sLine) as $value)
|
||||
{
|
||||
if (is_numeric($value))
|
||||
{
|
||||
$this->SetSkipLines(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
$this->SetSkipLines(1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
function ToArray($aFieldMap = null, $iMax = 0)
|
||||
{
|
||||
// $aFieldMap is an array of col_index=>col_name
|
||||
// $iMax is to limit the count of rows computed
|
||||
$aRes = array();
|
||||
|
||||
$iCount = 0;
|
||||
$iSkipped = 0;
|
||||
foreach(explode("\n", $this->m_sCSVData) as $sLine)
|
||||
{
|
||||
$sLine = trim($sLine);
|
||||
if (substr($sLine, 0, 1) == '#') continue;
|
||||
if (empty($sLine)) continue;
|
||||
|
||||
if ($iSkipped < $this->m_iSkip)
|
||||
{
|
||||
$iSkipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (explode($this->m_sSep, $sLine) as $iCol=>$sValue)
|
||||
{
|
||||
if (is_array($aFieldMap)) $sColRef = $aFieldMap[$iCol];
|
||||
else $sColRef = $iCol;
|
||||
$aRes[$iCount][$sColRef] = $sValue;
|
||||
}
|
||||
|
||||
$iCount++;
|
||||
if (($iMax > 0) && ($iCount >= $iMax)) break;
|
||||
}
|
||||
return $aRes;
|
||||
}
|
||||
|
||||
public function ListFields()
|
||||
{
|
||||
// Take the first valuable line
|
||||
foreach(explode("\n", $this->m_sCSVData) as $sLine)
|
||||
{
|
||||
$sLine = trim($sLine);
|
||||
if (substr($sLine, 0, 1) == '#') continue;
|
||||
if (empty($sLine)) continue;
|
||||
// We've got the first valuable line, that's it!
|
||||
break;
|
||||
}
|
||||
|
||||
$aRet = array();
|
||||
foreach (explode($this->m_sSep, $sLine) as $iCol=>$value)
|
||||
{
|
||||
if ($this->m_iSkip == 0)
|
||||
{
|
||||
// No header to help us
|
||||
$sLabel = "field $iCol";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sLabel = "$value";
|
||||
}
|
||||
$aRet[] = $sLabel;
|
||||
}
|
||||
return $aRet;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
362
core/data.generator.class.inc.php
Normal file
362
core/data.generator.class.inc.php
Normal file
@@ -0,0 +1,362 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* data generator
|
||||
* helps the consultants in creating dummy data sets, for various test purposes (validation, usability, scalability)
|
||||
*
|
||||
* @package tbd
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Data Generator helper class
|
||||
*
|
||||
* This class is useful to generate a lot of sample data that look consistent
|
||||
* for a given organization in order to simulate a real CMDB
|
||||
*/
|
||||
class cmdbDataGenerator
|
||||
{
|
||||
protected $m_sOrganizationKey;
|
||||
protected $m_sOrganizationCode;
|
||||
protected $m_sOrganizationName;
|
||||
protected $m_OrganizationDomains;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($sOrganizationId = "")
|
||||
{
|
||||
global $aCompanies, $aCompaniesCode;
|
||||
if ($sOrganizationId == '')
|
||||
{
|
||||
// No organization provided, pick a random and unused one from our predefined list
|
||||
$retries = 5*count($aCompanies);
|
||||
while ( ($retries > 0) && !isset($this->m_sOrganizationCode)) // Stupid algorithm, but I'm too lazy to do something bulletproof tonight
|
||||
{
|
||||
$index = rand(0, count($aCompanies) - 1);
|
||||
if (!$this->OrganizationExists($aCompanies[$index]['code']))
|
||||
{
|
||||
$this->m_sOrganizationCode = $aCompanies[$index]['code'];
|
||||
$this->m_sOrganizationName = $aCompanies[$index]['name'];
|
||||
$this->m_OrganizationDomains = $aCompanies[$index]['domain'];
|
||||
}
|
||||
$retries--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// A code has been provided, let's take the information we need from the organization itself
|
||||
$this->m_sOrganizationId = $sOrganizationId;
|
||||
$oOrg = $this->GetOrganization($sOrganizationId);
|
||||
if ($oOrg == null)
|
||||
{
|
||||
echo "Unable to find the organization '$sOrganisationCode' in the database... can not add objects into this organization.<br/>\n";
|
||||
exit();
|
||||
}
|
||||
$this->m_sOrganizationCode = $oOrg->Get('code');
|
||||
$this->m_sOrganizationName = $oOrg->Get('name');
|
||||
if (!isset($aCompaniesCode[$this->m_sOrganizationCode]['domain']))
|
||||
{
|
||||
// Generate some probable domain names for this organization
|
||||
$this->m_OrganizationDomains = array(strtolower($this->m_sOrganizationCode).".com", strtolower($this->m_sOrganizationCode).".org", strtolower($this->m_sOrganizationCode)."corp.net",);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pick the domain names for this organization from the predefined list
|
||||
$this->m_OrganizationDomains = $aCompaniesCode[$this->m_sOrganizationCode]['domain'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($this->m_sOrganizationCode))
|
||||
{
|
||||
echo "Unable to find an organization code which is not already used... can not create a new organization. Enhance the list of fake organizations (\$aCompanies in data_sample.inc.php).<br/>\n";
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current organization id used by the generator
|
||||
*
|
||||
* @return string The organization id
|
||||
*/
|
||||
public function GetOrganizationId()
|
||||
{
|
||||
return $this->m_sOrganizationId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current organization id used by the generator
|
||||
*
|
||||
* @param string The organization id
|
||||
* @return none
|
||||
*/
|
||||
public function SetOrganizationId($sId)
|
||||
{
|
||||
$this->m_sOrganizationId = $sId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current organization code used by the generator
|
||||
*
|
||||
* @return string The organization code
|
||||
*/
|
||||
public function GetOrganizationCode()
|
||||
{
|
||||
return $this->m_sOrganizationCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current organization name used by the generator
|
||||
*
|
||||
* @return string The organization name
|
||||
*/
|
||||
function GetOrganizationName()
|
||||
{
|
||||
return $this->m_sOrganizationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pseudo random first name taken from a (big) prefedined list
|
||||
*
|
||||
* @return string A random first name
|
||||
*/
|
||||
function GenerateFirstName()
|
||||
{
|
||||
global $aFirstNames;
|
||||
return $aFirstNames[rand(0, count($aFirstNames) - 1)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pseudo random last name taken from a (big) prefedined list
|
||||
*
|
||||
* @return string A random last name
|
||||
*/
|
||||
function GenerateLastName()
|
||||
{
|
||||
global $aNames;
|
||||
return $aNames[rand(0, count($aNames) - 1)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pseudo random country name taken from a prefedined list
|
||||
*
|
||||
* @return string A random city name
|
||||
*/
|
||||
function GenerateCountryName()
|
||||
{
|
||||
global $aCountries;
|
||||
return $aCountries[rand(0, count($aCountries) - 1)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pseudo random city name taken from a (big) prefedined list
|
||||
*
|
||||
* @return string A random city name
|
||||
*/
|
||||
function GenerateCityName()
|
||||
{
|
||||
global $aCities;
|
||||
return $aCities[rand(0, count($aCities) - 1)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pseudo random email address made of the first name, last name and organization's domain
|
||||
*
|
||||
* @return string A random email address
|
||||
*/
|
||||
function GenerateEmail($sFirstName, $sLastName)
|
||||
{
|
||||
if (rand(1, 20) > 18)
|
||||
{
|
||||
// some people (let's say 5~10%) have an irregular email address
|
||||
$sEmail = strtolower($this->CleanForEmail($sLastName))."@".strtolower($this->GenerateDomain());
|
||||
}
|
||||
else
|
||||
{
|
||||
$sEmail = strtolower($this->CleanForEmail($sFirstName)).".".strtolower($this->CleanForEmail($sLastName))."@".strtolower($this->GenerateDomain());
|
||||
}
|
||||
return $sEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate (pseudo) random strings that follow a given pattern
|
||||
*
|
||||
* The template is made of any number of 'parts' separated by pipes '|'
|
||||
* Each part is either:
|
||||
* - domain() => returns a domain name for the current organization
|
||||
* - enum(aaa,bb,c,dddd) => returns randomly one of aaa,bb,c or dddd with the same
|
||||
* probability of occurence. If you want to change the probability you can repeat some values
|
||||
* i.e enum(most probable,most probable,most probable,most probable,most probable,rare)
|
||||
* - number(xxx-yyy) => a random number between xxx and yyy (bounds included)
|
||||
* note that if the first number (xxx) begins with a zero, then the result will zero padded
|
||||
* to the same number of digits as xxx.
|
||||
* All other 'part' that does not follow one of the above mentioned pattern is returned as is
|
||||
*
|
||||
* Example: GenerateString("enum(sw,rtr,gw)|number(00-99)|.|domain()")
|
||||
* will produce strings like "sw01.netcmdb.com" or "rtr45.itop.org"
|
||||
*
|
||||
* @param string $sTemplate The template used for generating the string
|
||||
* @return string The generated pseudo random the string
|
||||
*/
|
||||
function GenerateString($sTemplate)
|
||||
{
|
||||
$sResult = "";
|
||||
$aParts = explode("\|", $sTemplate);
|
||||
foreach($aParts as $sPart)
|
||||
{
|
||||
if (preg_match("/domain\(\)/", $sPart, $aMatches))
|
||||
{
|
||||
$sResult .= strtolower($this->GenerateDomain());
|
||||
}
|
||||
elseif (preg_match("/enum\((.+)\)/", $sPart, $aMatches))
|
||||
{
|
||||
$sEnumValues = $aMatches[1];
|
||||
$aEnumValues = explode(",", $sEnumValues);
|
||||
$sResult .= $aEnumValues[rand(0, count($aEnumValues) - 1)];
|
||||
}
|
||||
elseif (preg_match("/number\((\d+)-(\d+)\)/", $sPart, $aMatches))
|
||||
{
|
||||
$sStartNumber = $aMatches[1];
|
||||
if ($sStartNumber[0] == '0')
|
||||
{
|
||||
// number must be zero padded
|
||||
$sFormat = "%0".strlen($sStartNumber)."d";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sFormat = "%d";
|
||||
}
|
||||
$sEndNumber = $aMatches[2];
|
||||
$sResult .= sprintf($sFormat, rand($sStartNumber, $sEndNumber));
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult .= $sPart;
|
||||
}
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a foreign key by picking a random element of the given class in a set limited by the given search criteria
|
||||
*
|
||||
* Example: GenerateKey("bizLocation", array('org_id', $oGenerator->GetOrganizationId());
|
||||
* will produce the foreign key of a Location object picked at random in the same organization
|
||||
*
|
||||
* @param string $sClass The name of the class to search for
|
||||
* @param string $aFilterCriteria A hash array of filterCOde => FilterValue (the strict operator '=' is used )
|
||||
* @return mixed The key to an object of the given class, or null if none are found
|
||||
*/
|
||||
function GenerateKey($sClass, $aFilterCriteria)
|
||||
{
|
||||
$retKey = null;
|
||||
$oFilter = new CMDBSearchFilter($sClass);
|
||||
foreach($aFilterCriteria as $sFilterCode => $filterValue)
|
||||
{
|
||||
$oFilter->AddCondition($sFilterCode, $filterValue, '=');
|
||||
}
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
if ($oSet->Count() > 0)
|
||||
{
|
||||
$max_count = $index = rand(1, $oSet->Count());
|
||||
do
|
||||
{
|
||||
$oObj = $oSet->Fetch();
|
||||
$index--;
|
||||
}
|
||||
while($index > 0);
|
||||
|
||||
if (!is_object($oObj))
|
||||
{
|
||||
echo "<pre>";
|
||||
echo "ERROR: non empty set, but invalid object picked! class='$sClass'\n";
|
||||
echo "Index chosen: $max_count\n";
|
||||
echo "The set is supposed to contain ".$oSet->Count()." object(s)\n";
|
||||
echo "Filter criteria:\n";
|
||||
print_r($aFilterCriteria);
|
||||
echo "</pre>";
|
||||
}
|
||||
else
|
||||
{
|
||||
$retKey = $oObj->GetKey();
|
||||
}
|
||||
}
|
||||
return $retKey;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Generate a (random) domain name consistent with the organization name & code
|
||||
*
|
||||
* The values are pulled from a (limited) predefined list. Note that a given
|
||||
* organization may have several domain names, so the result may be random
|
||||
*
|
||||
* @return string A domain name (like netcnmdb.com)
|
||||
*/
|
||||
protected function GenerateDomain()
|
||||
{
|
||||
if (is_array($this->m_OrganizationDomains))
|
||||
{
|
||||
$sDomain = $this->m_OrganizationDomains[rand(0, count($this->m_OrganizationDomains)-1)];
|
||||
}
|
||||
else
|
||||
{
|
||||
$sDomain = $this->m_OrganizationDomains;
|
||||
}
|
||||
return $sDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips accented characters from a string in order to produce a suitable email address
|
||||
*
|
||||
* @param string The text string to clean
|
||||
* @return string The cleanified text string
|
||||
*/
|
||||
protected function CleanForEmail($sText)
|
||||
{
|
||||
return str_replace(array("'", "é", "è", "ê", "ç", "à", "â", "ñ", "ö", "ä"), array("", "e", "e", "e", "c", "a", "a", "n", "oe", "ae"), $sText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an organization with the given code already exists in the database
|
||||
*
|
||||
* @param string $sCode The code to look for
|
||||
* @return boolean true if the given organization exists, false otherwise
|
||||
*/
|
||||
protected function OrganizationExists($sCode)
|
||||
{
|
||||
$oFilter = new CMDBSearchFilter('bizOrganization');
|
||||
$oFilter->AddCondition('code', $sCode, '=');
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
return ($oSet->Count() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for an organization with the given code in the database
|
||||
*
|
||||
* @param string $Id The organization Id to look for
|
||||
* @return cmdbOrganization the organization if it exists, null otherwise
|
||||
*/
|
||||
protected function GetOrganization($sId)
|
||||
{
|
||||
$oOrg = null;
|
||||
$oFilter = new CMDBSearchFilter('bizOrganization');
|
||||
$oFilter->AddCondition('pkey', $sId, '=');
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
if ($oSet->Count() > 0)
|
||||
{
|
||||
$oOrg = $oSet->Fetch(); // Let's take the first one found
|
||||
}
|
||||
return $oOrg;
|
||||
}
|
||||
}
|
||||
?>
|
||||
1023
core/dbobject.class.php
Normal file
1023
core/dbobject.class.php
Normal file
File diff suppressed because it is too large
Load Diff
1045
core/dbobjectsearch.class.php
Normal file
1045
core/dbobjectsearch.class.php
Normal file
File diff suppressed because it is too large
Load Diff
276
core/dbobjectset.class.php
Normal file
276
core/dbobjectset.class.php
Normal file
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* A set of persistent objects, could be heterogeneous
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
class DBObjectSet
|
||||
{
|
||||
private $m_oFilter;
|
||||
private $m_aOrderBy;
|
||||
public $m_bLoaded;
|
||||
private $m_aData;
|
||||
private $m_aId2Row;
|
||||
private $m_iCurrRow;
|
||||
|
||||
public function __construct(DBObjectSearch $oFilter, $aOrderBy = array(), $aArgs = array())
|
||||
{
|
||||
$this->m_oFilter = $oFilter;
|
||||
$this->m_aOrderBy = $aOrderBy;
|
||||
$this->m_aArgs = $aArgs;
|
||||
|
||||
$this->m_bLoaded = false;
|
||||
$this->m_aData = array();
|
||||
$this->m_aId2Row = array();
|
||||
$this->m_iCurrRow = 0;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
$sRet = '';
|
||||
$this->Rewind();
|
||||
$sRet .= "Set (".$this->m_oFilter->ToSibuSQL().")<br/>\n";
|
||||
$sRet .= "Query: <pre style=\"font-size: smaller; display:inline;\">".MetaModel::MakeSelectQuery($this->m_oFilter, array()).")</pre>\n";
|
||||
|
||||
$sRet .= $this->Count()." records<br/>\n";
|
||||
if ($this->Count() > 0)
|
||||
{
|
||||
$sRet .= "<ul class=\"treeview\">\n";
|
||||
while ($oObj = $this->Fetch())
|
||||
{
|
||||
$sRet .= "<li>".$oObj->__toString()."</li>\n";
|
||||
}
|
||||
$sRet .= "</ul>\n";
|
||||
}
|
||||
return $sRet;
|
||||
}
|
||||
|
||||
static public function FromObject($oObject)
|
||||
{
|
||||
$oRetSet = self::FromScratch(get_class($oObject));
|
||||
$oRetSet->AddObject($oObject);
|
||||
return $oRetSet;
|
||||
}
|
||||
|
||||
static public function FromScratch($sClass)
|
||||
{
|
||||
$oFilter = new CMDBSearchFilter($sClass);
|
||||
$oRetSet = new self($oFilter);
|
||||
$oRetSet->m_bLoaded = true; // no DB load
|
||||
return $oRetSet;
|
||||
}
|
||||
|
||||
static public function FromArray($sClass, $aObjects)
|
||||
{
|
||||
$oFilter = new CMDBSearchFilter($sClass);
|
||||
$oRetSet = new self($oFilter);
|
||||
$oRetSet->m_bLoaded = true; // no DB load
|
||||
$oRetSet->AddObjectArray($aObjects);
|
||||
return $oRetSet;
|
||||
}
|
||||
|
||||
public function ToArray($bWithId = true)
|
||||
{
|
||||
$aRet = array();
|
||||
$this->Rewind();
|
||||
while ($oObject = $this->Fetch())
|
||||
{
|
||||
if ($bWithId)
|
||||
{
|
||||
$aRet[$oObject->GetKey()] = $oObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aRet[] = $oObject;
|
||||
}
|
||||
}
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
public function GetColumnAsArray($sAttCode, $bWithId = true)
|
||||
{
|
||||
$aRet = array();
|
||||
$this->Rewind();
|
||||
while ($oObject = $this->Fetch())
|
||||
{
|
||||
if ($bWithId)
|
||||
{
|
||||
$aRet[$oObject->GetKey()] = $oObject->Get($sAttCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aRet[] = $oObject->Get($sAttCode);
|
||||
}
|
||||
}
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
public function GetFilter()
|
||||
{
|
||||
return $this->m_oFilter;
|
||||
}
|
||||
|
||||
public function GetClass()
|
||||
{
|
||||
return $this->m_oFilter->GetClass();
|
||||
}
|
||||
|
||||
public function GetRootClass()
|
||||
{
|
||||
return MetaModel::GetRootClass($this->GetClass());
|
||||
}
|
||||
|
||||
public function Load()
|
||||
{
|
||||
if ($this->m_bLoaded) return;
|
||||
|
||||
$sSQL = MetaModel::MakeSelectQuery($this->m_oFilter, $this->m_aOrderBy, $this->m_aArgs);
|
||||
$resQuery = CMDBSource::Query($sSQL);
|
||||
if (!$resQuery) return;
|
||||
|
||||
while ($aRow = CMDBSource::FetchArray($resQuery))
|
||||
{
|
||||
$sClass = $this->m_oFilter->GetClass();
|
||||
$oObject = MetaModel::GetObjectByRow($sClass, $aRow);
|
||||
$this->AddObject($oObject);
|
||||
}
|
||||
CMDBSource::FreeResult($resQuery);
|
||||
|
||||
$this->m_bLoaded = true;
|
||||
}
|
||||
|
||||
public function Count()
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
return count($this->m_aData);
|
||||
}
|
||||
|
||||
public function Fetch()
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
if ($this->m_iCurrRow >= count($this->m_aData))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
$oRetObj = $this->m_aData[$this->m_iCurrRow];
|
||||
$this->m_iCurrRow++;
|
||||
return $oRetObj;
|
||||
}
|
||||
|
||||
public function Rewind()
|
||||
{
|
||||
$this->Seek(0);
|
||||
}
|
||||
|
||||
public function Seek($iRow)
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
$this->m_iCurrRow = min($iRow, count($this->m_aData));
|
||||
return $this->m_iCurrRow;
|
||||
}
|
||||
|
||||
public function AddObject($oObject)
|
||||
{
|
||||
// ?usefull? if ($oObject->GetClass() != $this->GetClass()) return;
|
||||
|
||||
// it is mandatory to avoid duplicates
|
||||
if (array_key_exists($oObject->GetKey(), $this->m_aId2Row)) return;
|
||||
|
||||
// Do not load here, because the load uses that method too
|
||||
$iNextPos = count($this->m_aData);
|
||||
$this->m_aData[$iNextPos] = $oObject;
|
||||
$this->m_aId2Row[$oObject->GetKey()] = $iNextPos;
|
||||
}
|
||||
|
||||
public function AddObjectArray($aObjects)
|
||||
{
|
||||
foreach ($aObjects as $oObj)
|
||||
{
|
||||
$this->AddObject($oObj);
|
||||
}
|
||||
}
|
||||
|
||||
public function Merge($oObjectSet)
|
||||
{
|
||||
if ($this->GetRootClass() != $oObjectSet->GetRootClass())
|
||||
{
|
||||
throw new CoreException("Could not merge two objects sets if they don't have the same root class");
|
||||
}
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
$oObjectSet->Seek(0);
|
||||
while ($oObject = $oObjectSet->Fetch())
|
||||
{
|
||||
$this->AddObject($oObject);
|
||||
}
|
||||
}
|
||||
|
||||
public function CreateIntersect($oObjectSet)
|
||||
{
|
||||
if ($this->GetRootClass() != $oObjectSet->GetRootClass())
|
||||
{
|
||||
throw new CoreException("Could not 'intersect' two objects sets if they don't have the same root class");
|
||||
}
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
$oNewSet = DBObjectSet::FromScratch($this->GetClass());
|
||||
|
||||
$oObjectSet->Seek(0);
|
||||
while ($oObject = $oObjectSet->Fetch())
|
||||
{
|
||||
if (array_key_exists($oObject->GetKey(), $this->m_aId2Row))
|
||||
{
|
||||
$oNewSet->AddObject($oObject);
|
||||
}
|
||||
}
|
||||
return $oNewSet;
|
||||
}
|
||||
|
||||
public function CreateDelta($oObjectSet)
|
||||
{
|
||||
if ($this->GetRootClass() != $oObjectSet->GetRootClass())
|
||||
{
|
||||
throw new CoreException("Could not 'delta' two objects sets if they don't have the same root class");
|
||||
}
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
$oNewSet = DBObjectSet::FromScratch($this->GetClass());
|
||||
|
||||
$oObjectSet->Seek(0);
|
||||
while ($oObject = $oObjectSet->Fetch())
|
||||
{
|
||||
if (!array_key_exists($oObject->GetKey(), $this->m_aId2Row))
|
||||
{
|
||||
$oNewSet->AddObject($oObject);
|
||||
}
|
||||
}
|
||||
return $oNewSet;
|
||||
}
|
||||
|
||||
public function GetRelatedObjects($sRelCode, $iMaxDepth = 99)
|
||||
{
|
||||
$aVisited = array(); // optimization for consecutive calls of MetaModel::GetRelatedObjects
|
||||
$this->Seek(0);
|
||||
while ($oObject = $this->Fetch())
|
||||
{
|
||||
$aRelatedObjs = $oObject->GetRelatedObjects($sRelCode, $iMaxDepth, $aVisited);
|
||||
}
|
||||
return $aRelatedObjs;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
123
core/email.class.inc.php
Normal file
123
core/email.class.inc.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Send an mail (for notification, testing,... purposes)
|
||||
* #@# TODO - replace by a more sophisticated mean (and update the prototype)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class EMail
|
||||
{
|
||||
protected $m_sBody;
|
||||
protected $m_sSubject;
|
||||
protected $m_sTo;
|
||||
protected $m_aHeaders; // array of key=>value
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->m_sTo = '';
|
||||
$this->m_sSubject = '';
|
||||
$this->m_sBody = '';
|
||||
$this->m_aHeaders = array();
|
||||
}
|
||||
|
||||
|
||||
// Errors management : not that simple because we need that function to be
|
||||
// executed in the background, while making sure that any issue would be reported clearly
|
||||
protected $m_aMailErrors; //array of strings explaining the issues
|
||||
|
||||
public function mail_error_handler($errno, $errstr, $errfile, $errline)
|
||||
{
|
||||
$sCleanMessage= str_replace("mail() [<a href='function.mail'>function.mail</a>]: ", "", $errstr);
|
||||
$this->m_aMailErrors[] = $sCleanMessage;
|
||||
}
|
||||
|
||||
|
||||
// returns a list of issues if any
|
||||
public function Send()
|
||||
{
|
||||
$sHeaders = 'MIME-Version: 1.0' . "\r\n";
|
||||
// ! the case is important for MS-Outlook
|
||||
$sHeaders .= 'Content-Type: text/html; charset=UTF-8' . "\r\n";
|
||||
$sHeaders .= 'Content-Transfer-Encoding: 8bit' . "\r\n";
|
||||
foreach ($this->m_aHeaders as $sKey => $sValue)
|
||||
{
|
||||
$sHeaders .= "$sKey: $sValue\r\n";
|
||||
}
|
||||
|
||||
// Under Windows (not yet proven for Linux/PHP) mail may issue a warning
|
||||
// that I could not mask (tried error_reporting(), etc.)
|
||||
$this->m_aMailErrors = array();
|
||||
set_error_handler(array($this, 'mail_error_handler'));
|
||||
$bRes = mail
|
||||
(
|
||||
$this->m_sTo,
|
||||
$this->m_sSubject,
|
||||
$this->m_sBody,
|
||||
$sHeaders
|
||||
);
|
||||
restore_error_handler();
|
||||
if (!$bRes && empty($this->m_aMailErrors))
|
||||
{
|
||||
$this->m_aMailErrors[] = 'Unknown reason';
|
||||
}
|
||||
return $this->m_aMailErrors;
|
||||
}
|
||||
|
||||
protected function AddToHeader($sKey, $sValue)
|
||||
{
|
||||
if (strlen($sValue) > 0)
|
||||
{
|
||||
$this->m_aHeaders[$sKey] = $sValue;
|
||||
}
|
||||
}
|
||||
|
||||
public function SetBody($sBody)
|
||||
{
|
||||
$this->m_sBody = $sBody;
|
||||
}
|
||||
|
||||
public function SetSubject($aSubject)
|
||||
{
|
||||
$this->m_sSubject = $aSubject;
|
||||
}
|
||||
|
||||
public function SetRecipientTO($sAddress)
|
||||
{
|
||||
$this->m_sTo = $sAddress;
|
||||
}
|
||||
|
||||
public function SetRecipientCC($sAddress)
|
||||
{
|
||||
$this->AddToHeader('Cc', $sAddress);
|
||||
}
|
||||
|
||||
public function SetRecipientBCC($sAddress)
|
||||
{
|
||||
$this->AddToHeader('Bcc', $sAddress);
|
||||
}
|
||||
|
||||
public function SetRecipientFrom($sAddress)
|
||||
{
|
||||
$this->AddToHeader('From', $sAddress);
|
||||
|
||||
// This is required on Windows because otherwise I would get the error
|
||||
// "sendmail_from" not set in php.ini" even if it is correctly working
|
||||
// (apparently, once it worked the SMTP server won't claim anymore for it)
|
||||
ini_set("sendmail_from", $sAddress);
|
||||
}
|
||||
|
||||
public function SetRecipientReplyTo($sAddress)
|
||||
{
|
||||
$this->AddToHeader('Reply-To', $sAddress);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
215
core/event.class.inc.php
Normal file
215
core/event.class.inc.php
Normal file
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* An application internal event
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class Event extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "Log Event",
|
||||
"description" => "An application internal event",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_event",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "realclass",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeText("message", array("label"=>"message", "description"=>"short description of the event", "allowed_values"=>null, "sql"=>"message", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDate("date", array("label"=>"date", "description"=>"date and time at which the changes have been recorded", "allowed_values"=>null, "sql"=>"date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("label"=>"user info", "description"=>"identification of the user that was doing the action that triggered this event", "allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("message");
|
||||
MetaModel::Init_AddFilterFromAttribute("date");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('message', 'date', 'userinfo')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'finalclass', 'message')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
|
||||
class EventNotification extends Event
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "Notification event",
|
||||
"description" => "Trace of a notification that has been sent",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_event_notification",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("trigger_id", array("targetclass"=>"Trigger", "jointype"=> "", "label"=>"Trigger", "description"=>"user account", "allowed_values"=>null, "sql"=>"trigger_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("action_id", array("targetclass"=>"Action", "jointype"=> "", "label"=>"user", "description"=>"user account", "allowed_values"=>null, "sql"=>"action_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("object_id", array("label"=>"Object id", "description"=>"object id (class defined by the trigger ?)", "allowed_values"=>null, "sql"=>"object_id", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("trigger_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("action_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("object_id");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'trigger_id', 'action_id', 'object_id')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class EventNotificationEmail extends EventNotification
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "Email emission event",
|
||||
"description" => "Trace of an email that has been sent",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_event_email",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeText("to", array("label"=>"TO", "description"=>"TO", "allowed_values"=>null, "sql"=>"to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("cc", array("label"=>"CC", "description"=>"CC", "allowed_values"=>null, "sql"=>"cc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("bcc", array("label"=>"BCC", "description"=>"BCC", "allowed_values"=>null, "sql"=>"bcc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("from", array("label"=>"From", "description"=>"Sender of the message", "allowed_values"=>null, "sql"=>"from", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("subject", array("label"=>"Subject", "description"=>"Subject", "allowed_values"=>null, "sql"=>"subject", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("body", array("label"=>"Body", "description"=>"Body", "allowed_values"=>null, "sql"=>"body", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_InheritFilters();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'message', 'trigger_id', 'action_id', 'object_id', 'to', 'cc', 'bcc', 'from', 'subject', 'body')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'message', 'subject')); // Attributes to be displayed for a list
|
||||
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class EventIssue extends Event
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "Issue event",
|
||||
"description" => "Trace of an issue (warning, error, etc.)",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_event_issue",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("issue", array("label"=>"Issue", "description"=>"What happened", "allowed_values"=>null, "sql"=>"issue", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("impact", array("label"=>"Impact", "description"=>"What are the consequences", "allowed_values"=>null, "sql"=>"impact", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("page", array("label"=>"Page", "description"=>"HTTP entry point", "allowed_values"=>null, "sql"=>"page", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("arguments_post", array("label"=>"Posted arguments", "description"=>"HTTP POST arguments", "allowed_values"=>null, "sql"=>"arguments_post", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("arguments_get", array("label"=>"URL arguments", "description"=>"HTTP GET arguments", "allowed_values"=>null, "sql"=>"arguments_get", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("callstack", array("label"=>"Callstack", "description"=>"Call stack", "allowed_values"=>null, "sql"=>"callstack", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeBlob("data", array("label"=>"Data", "description"=>"More information", "allowed_values"=>null, "sql"=>"data", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("issue");
|
||||
MetaModel::Init_AddFilterFromAttribute("impact");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'issue', 'impact', 'page', 'arguments_post', 'arguments_get', 'callstack', 'data')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'issue', 'impact')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class EventWebService extends Event
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "Web service event",
|
||||
"description" => "Trace of an web service call",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_event_webservice",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("verb", array("label"=>"Verb", "description"=>"Name of the operation", "allowed_values"=>null, "sql"=>"verb", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
//MetaModel::Init_AddAttribute(new AttributeStructure("arguments", array("label"=>"Arguments", "description"=>"Operation arguments", "allowed_values"=>null, "sql"=>"data", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeBoolean("result", array("label"=>"Result", "description"=>"Overall success/failure", "allowed_values"=>null, "sql"=>"result", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("log_info", array("label"=>"Info log", "description"=>"Result info log", "allowed_values"=>null, "sql"=>"log_info", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("log_warning", array("label"=>"Warning log", "description"=>"Result warning log", "allowed_values"=>null, "sql"=>"log_warning", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("log_error", array("label"=>"Error log", "description"=>"Result error log", "allowed_values"=>null, "sql"=>"log_error", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("data", array("label"=>"Data", "description"=>"Result data", "allowed_values"=>null, "sql"=>"data", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'verb', 'result', 'log_info', 'log_warning', 'log_error', 'data')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'verb', 'result')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
541
core/expression.class.inc.php
Normal file
541
core/expression.class.inc.php
Normal file
@@ -0,0 +1,541 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* General definition of an expression tree (could be OQL, SQL or whatever)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
class MissingQueryArgument extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
abstract class Expression
|
||||
{
|
||||
// recursive translation of identifiers
|
||||
abstract public function Translate($aTranslationData, $bMatchAll = true);
|
||||
|
||||
// recursive rendering (aArgs used as input by default, or used as output if bRetrofitParams set to True
|
||||
abstract public function Render(&$aArgs = null, $bRetrofitParams = false);
|
||||
|
||||
// recursively builds an array of class => fieldname
|
||||
abstract public function ListRequiredFields();
|
||||
|
||||
abstract public function IsTrue();
|
||||
|
||||
public function RequiresField($sClass, $sFieldName)
|
||||
{
|
||||
// #@# todo - optimize : this is called quite often when building a single query !
|
||||
$aRequired = $this->ListRequiredFields();
|
||||
if (!in_array($sClass.'.'.$sFieldName, $aRequired)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function serialize()
|
||||
{
|
||||
return base64_encode($this->Render());
|
||||
}
|
||||
|
||||
static public function unserialize($sValue)
|
||||
{
|
||||
return self::FromOQL(base64_decode($sValue));
|
||||
}
|
||||
|
||||
static public function FromOQL($sConditionExpr)
|
||||
{
|
||||
$oOql = new OqlInterpreter($sConditionExpr);
|
||||
$oExpression = $oOql->ParseExpression();
|
||||
|
||||
return $oExpression;
|
||||
}
|
||||
|
||||
public function LogAnd($oExpr)
|
||||
{
|
||||
if ($this->IsTrue()) return clone $oExpr;
|
||||
if ($oExpr->IsTrue()) return clone $this;
|
||||
return new BinaryExpression($this, 'AND', $oExpr);
|
||||
}
|
||||
|
||||
public function LogOr($oExpr)
|
||||
{
|
||||
return new BinaryExpression($this, 'OR', $oExpr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class BinaryExpression extends Expression
|
||||
{
|
||||
protected $m_oLeftExpr; // filter code or an SQL expression (later?)
|
||||
protected $m_oRightExpr;
|
||||
protected $m_sOperator;
|
||||
|
||||
public function __construct($oLeftExpr, $sOperator, $oRightExpr)
|
||||
{
|
||||
if (!is_object($oLeftExpr))
|
||||
{
|
||||
throw new CoreException('Expecting an Expression object on the left hand', array('found_type' => gettype($oLeftExpr)));
|
||||
}
|
||||
if (!is_object($oRightExpr))
|
||||
{
|
||||
throw new CoreException('Expecting an Expression object on the right hand', array('found_type' => gettype($oRightExpr)));
|
||||
}
|
||||
if (!$oLeftExpr instanceof Expression)
|
||||
{
|
||||
throw new CoreException('Expecting an Expression object on the left hand', array('found_class' => get_class($oLeftExpr)));
|
||||
}
|
||||
if (!$oRightExpr instanceof Expression)
|
||||
{
|
||||
throw new CoreException('Expecting an Expression object on the right hand', array('found_class' => get_class($oRightExpr)));
|
||||
}
|
||||
$this->m_oLeftExpr = $oLeftExpr;
|
||||
$this->m_oRightExpr = $oRightExpr;
|
||||
$this->m_sOperator = $sOperator;
|
||||
}
|
||||
|
||||
public function IsTrue()
|
||||
{
|
||||
// return true if we are certain that it will be true
|
||||
if ($this->m_sOperator == 'AND')
|
||||
{
|
||||
if ($this->m_oLeftExpr->IsTrue() && $this->m_oLeftExpr->IsTrue()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function GetLeftExpr()
|
||||
{
|
||||
return $this->m_oLeftExpr;
|
||||
}
|
||||
|
||||
public function GetRightExpr()
|
||||
{
|
||||
return $this->m_oRightExpr;
|
||||
}
|
||||
|
||||
public function GetOperator()
|
||||
{
|
||||
return $this->m_sOperator;
|
||||
}
|
||||
|
||||
// recursive rendering
|
||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||
{
|
||||
$sOperator = $this->GetOperator();
|
||||
$sLeft = $this->GetLeftExpr()->Render($aArgs, $bRetrofitParams);
|
||||
$sRight = $this->GetRightExpr()->Render($aArgs, $bRetrofitParams);
|
||||
return "($sLeft $sOperator $sRight)";
|
||||
}
|
||||
|
||||
public function Translate($aTranslationData, $bMatchAll = true)
|
||||
{
|
||||
$oLeft = $this->GetLeftExpr()->Translate($aTranslationData, $bMatchAll);
|
||||
$oRight = $this->GetRightExpr()->Translate($aTranslationData, $bMatchAll);
|
||||
return new BinaryExpression($oLeft, $this->GetOperator(), $oRight);
|
||||
}
|
||||
|
||||
public function ListRequiredFields()
|
||||
{
|
||||
$aLeft = $this->GetLeftExpr()->ListRequiredFields();
|
||||
$aRight = $this->GetRightExpr()->ListRequiredFields();
|
||||
return array_merge($aLeft, $aRight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class UnaryExpression extends Expression
|
||||
{
|
||||
protected $m_value;
|
||||
|
||||
public function __construct($value)
|
||||
{
|
||||
$this->m_value = $value;
|
||||
}
|
||||
|
||||
public function IsTrue()
|
||||
{
|
||||
// return true if we are certain that it will be true
|
||||
return ($this->m_value == 1);
|
||||
}
|
||||
|
||||
public function GetValue()
|
||||
{
|
||||
return $this->m_value;
|
||||
}
|
||||
|
||||
// recursive rendering
|
||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||
{
|
||||
if ($bRetrofitParams)
|
||||
{
|
||||
$iParamIndex = count($aArgs) + 1; // 1-based indexation
|
||||
$aArgs['param'.$iParamIndex] = $this->m_value;
|
||||
return ':param'.$iParamIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CMDBSource::Quote($this->m_value);
|
||||
}
|
||||
}
|
||||
|
||||
public function Translate($aTranslationData, $bMatchAll = true)
|
||||
{
|
||||
return clone $this;
|
||||
}
|
||||
|
||||
public function ListRequiredFields()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
class ScalarExpression extends UnaryExpression
|
||||
{
|
||||
public function __construct($value)
|
||||
{
|
||||
if (!is_scalar($value))
|
||||
{
|
||||
throw new CoreException('Attempt to create a scalar expression from a non scalar', array('var_type'=>gettype($value)));
|
||||
}
|
||||
parent::__construct($value);
|
||||
}
|
||||
}
|
||||
|
||||
class TrueExpression extends ScalarExpression
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(1);
|
||||
}
|
||||
|
||||
public function IsTrue()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class FieldExpression extends UnaryExpression
|
||||
{
|
||||
protected $m_sParent;
|
||||
protected $m_sName;
|
||||
|
||||
public function __construct($sName, $sParent = '')
|
||||
{
|
||||
parent::__construct("$sParent.$sName");
|
||||
|
||||
$this->m_sParent = $sParent;
|
||||
$this->m_sName = $sName;
|
||||
}
|
||||
|
||||
public function IsTrue()
|
||||
{
|
||||
// return true if we are certain that it will be true
|
||||
return false;
|
||||
}
|
||||
|
||||
public function GetParent() {return $this->m_sParent;}
|
||||
public function GetName() {return $this->m_sName;}
|
||||
|
||||
// recursive rendering
|
||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||
{
|
||||
if (empty($this->m_sParent))
|
||||
{
|
||||
return "`{$this->m_sName}`";
|
||||
}
|
||||
return "`{$this->m_sParent}`.`{$this->m_sName}`";
|
||||
}
|
||||
|
||||
public function Translate($aTranslationData, $bMatchAll = true)
|
||||
{
|
||||
if (!array_key_exists($this->m_sParent, $aTranslationData))
|
||||
{
|
||||
if ($bMatchAll) throw new CoreException('Unknown parent id in translation table', array('parent_id' => $this->m_sParent, 'translation_table' => array_keys($aTranslationData)));
|
||||
return clone $this;
|
||||
}
|
||||
if (!array_key_exists($this->m_sName, $aTranslationData[$this->m_sParent]))
|
||||
{
|
||||
if (!array_key_exists('*', $aTranslationData[$this->m_sParent]))
|
||||
{
|
||||
// #@# debug - if ($bMatchAll) MyHelpers::var_dump_html($aTranslationData, true);
|
||||
if ($bMatchAll) throw new CoreException('Unknown name in translation table', array('name' => $this->m_sName, 'parent_id' => $this->m_sParent, 'translation_table' => array_keys($aTranslationData[$this->m_sParent])));
|
||||
return clone $this;
|
||||
}
|
||||
$sNewParent = $aTranslationData[$this->m_sParent]['*'];
|
||||
$sNewName = $this->m_sName;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sNewParent = $aTranslationData[$this->m_sParent][$this->m_sName][0];
|
||||
$sNewName = $aTranslationData[$this->m_sParent][$this->m_sName][1];
|
||||
}
|
||||
return new FieldExpression($sNewName, $sNewParent);
|
||||
}
|
||||
|
||||
public function ListRequiredFields()
|
||||
{
|
||||
return array($this->m_sParent.'.'.$this->m_sName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class VariableExpression extends UnaryExpression
|
||||
{
|
||||
protected $m_sName;
|
||||
|
||||
public function __construct($sName)
|
||||
{
|
||||
parent::__construct($sName);
|
||||
|
||||
$this->m_sName = $sName;
|
||||
}
|
||||
|
||||
public function IsTrue()
|
||||
{
|
||||
// return true if we are certain that it will be true
|
||||
return false;
|
||||
}
|
||||
|
||||
public function GetName() {return $this->m_sName;}
|
||||
|
||||
// recursive rendering
|
||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||
{
|
||||
if (is_null($aArgs))
|
||||
{
|
||||
return ':'.$this->m_sName;
|
||||
}
|
||||
elseif (array_key_exists($this->m_sName, $aArgs))
|
||||
{
|
||||
return CMDBSource::Quote($aArgs[$this->m_sName]);
|
||||
}
|
||||
elseif ($bRetrofitParams)
|
||||
{
|
||||
//$aArgs[$this->m_sName] = null;
|
||||
return ':'.$this->m_sName;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new MissingQueryArgument('Missing query argument', array('expecting'=>$this->m_sName, 'available'=>$aArgs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Temporary, until we implement functions and expression casting!
|
||||
// ... or until we implement a real full text search based in the MATCH() expression
|
||||
class ListExpression extends Expression
|
||||
{
|
||||
protected $m_aExpressions;
|
||||
|
||||
public function __construct($aExpressions)
|
||||
{
|
||||
$this->m_aExpressions = $aExpressions;
|
||||
}
|
||||
|
||||
public function IsTrue()
|
||||
{
|
||||
// return true if we are certain that it will be true
|
||||
return false;
|
||||
}
|
||||
|
||||
public function GetItems()
|
||||
{
|
||||
return $this->m_aExpressions;
|
||||
}
|
||||
|
||||
// recursive rendering
|
||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||
{
|
||||
$aRes = array();
|
||||
foreach ($this->m_aExpressions as $oExpr)
|
||||
{
|
||||
$aRes[] = $oExpr->Render($aArgs, $bRetrofitParams);
|
||||
}
|
||||
return '('.implode(', ', $aRes).')';
|
||||
}
|
||||
|
||||
public function Translate($aTranslationData, $bMatchAll = true)
|
||||
{
|
||||
$aRes = array();
|
||||
foreach ($this->m_aExpressions as $oExpr)
|
||||
{
|
||||
$aRes[] = $oExpr->Translate($aTranslationData, $bMatchAll);
|
||||
}
|
||||
return new ListExpression($aRes);
|
||||
}
|
||||
|
||||
public function ListRequiredFields()
|
||||
{
|
||||
$aRes = array();
|
||||
foreach ($this->m_aExpressions as $oExpr)
|
||||
{
|
||||
$aRes = array_merge($aRes, $oExpr->ListRequiredFields());
|
||||
}
|
||||
return $aRes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class FunctionExpression extends Expression
|
||||
{
|
||||
protected $m_sVerb;
|
||||
protected $m_aArgs; // array of expressions
|
||||
|
||||
public function __construct($sVerb, $aArgExpressions)
|
||||
{
|
||||
$this->m_sVerb = $sVerb;
|
||||
$this->m_aArgs = $aArgExpressions;
|
||||
}
|
||||
|
||||
public function IsTrue()
|
||||
{
|
||||
// return true if we are certain that it will be true
|
||||
return false;
|
||||
}
|
||||
|
||||
public function GetVerb()
|
||||
{
|
||||
return $this->m_sVerb;
|
||||
}
|
||||
|
||||
public function GetArgs()
|
||||
{
|
||||
return $this->m_aArgs;
|
||||
}
|
||||
|
||||
// recursive rendering
|
||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||
{
|
||||
$aRes = array();
|
||||
foreach ($this->m_aArgs as $oExpr)
|
||||
{
|
||||
$aRes[] = $oExpr->Render($aArgs, $bRetrofitParams);
|
||||
}
|
||||
return $this->m_sVerb.'('.implode(', ', $aRes).')';
|
||||
}
|
||||
|
||||
public function Translate($aTranslationData, $bMatchAll = true)
|
||||
{
|
||||
$aRes = array();
|
||||
foreach ($this->m_aArgs as $oExpr)
|
||||
{
|
||||
$aRes[] = $oExpr->Translate($aTranslationData, $bMatchAll);
|
||||
}
|
||||
return new FunctionExpression($this->m_sVerb, $aRes);
|
||||
}
|
||||
|
||||
public function ListRequiredFields()
|
||||
{
|
||||
$aRes = array();
|
||||
foreach ($this->m_aArgs as $oExpr)
|
||||
{
|
||||
$aRes = array_merge($aRes, $oExpr->ListRequiredFields());
|
||||
}
|
||||
return $aRes;
|
||||
}
|
||||
}
|
||||
|
||||
class IntervalExpression extends Expression
|
||||
{
|
||||
protected $m_oValue; // expression
|
||||
protected $m_sUnit;
|
||||
|
||||
public function __construct($oValue, $sUnit)
|
||||
{
|
||||
$this->m_oValue = $oValue;
|
||||
$this->m_sUnit = $sUnit;
|
||||
}
|
||||
|
||||
public function IsTrue()
|
||||
{
|
||||
// return true if we are certain that it will be true
|
||||
return false;
|
||||
}
|
||||
|
||||
public function GetValue()
|
||||
{
|
||||
return $this->m_oValue;
|
||||
}
|
||||
|
||||
public function GetUnit()
|
||||
{
|
||||
return $this->m_sUnit;
|
||||
}
|
||||
|
||||
// recursive rendering
|
||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||
{
|
||||
return 'INTERVAL '.$this->m_oValue->Render($aArgs, $bRetrofitParams).' '.$this->m_sUnit;
|
||||
}
|
||||
|
||||
public function Translate($aTranslationData, $bMatchAll = true)
|
||||
{
|
||||
return new IntervalExpression($this->m_oValue->Translate($aTranslationData, $bMatchAll), $this->m_sUnit);
|
||||
}
|
||||
|
||||
public function ListRequiredFields()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
class CharConcatExpression extends Expression
|
||||
{
|
||||
protected $m_aExpressions;
|
||||
|
||||
public function __construct($aExpressions)
|
||||
{
|
||||
$this->m_aExpressions = $aExpressions;
|
||||
}
|
||||
|
||||
public function IsTrue()
|
||||
{
|
||||
// return true if we are certain that it will be true
|
||||
return false;
|
||||
}
|
||||
|
||||
public function GetItems()
|
||||
{
|
||||
return $this->m_aExpressions;
|
||||
}
|
||||
|
||||
// recursive rendering
|
||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||
{
|
||||
$aRes = array();
|
||||
foreach ($this->m_aExpressions as $oExpr)
|
||||
{
|
||||
$sCol = $oExpr->Render($aArgs, $bRetrofitParams);
|
||||
// Concat will be globally NULL if one single argument is null !
|
||||
$aRes[] = "COALESCE($sCol, '')";
|
||||
}
|
||||
return "CAST(CONCAT(".implode(', ', $aRes).") AS CHAR)";
|
||||
}
|
||||
|
||||
public function Translate($aTranslationData, $bMatchAll = true)
|
||||
{
|
||||
$aRes = array();
|
||||
foreach ($this->m_aExpressions as $oExpr)
|
||||
{
|
||||
$aRes[] = $oExpr->Translate($aTranslationData, $bMatchAll);
|
||||
}
|
||||
return new CharConcatExpression($aRes);
|
||||
}
|
||||
|
||||
public function ListRequiredFields()
|
||||
{
|
||||
$aRes = array();
|
||||
foreach ($this->m_aExpressions as $oExpr)
|
||||
{
|
||||
$aRes = array_merge($aRes, $oExpr->ListRequiredFields());
|
||||
}
|
||||
return $aRes;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
216
core/filterdef.class.inc.php
Normal file
216
core/filterdef.class.inc.php
Normal file
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
|
||||
|
||||
require_once('MyHelpers.class.inc.php');
|
||||
|
||||
|
||||
/**
|
||||
* Definition of a filter (could be made out of an existing attribute, or from an expression)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
abstract class FilterDefinition
|
||||
{
|
||||
abstract public function GetType();
|
||||
abstract public function GetTypeDesc();
|
||||
|
||||
protected $m_sCode;
|
||||
private $m_aParams = array();
|
||||
protected function Get($sParamName) {return $this->m_aParams[$sParamName];}
|
||||
|
||||
public function __construct($sCode, $aParams = array())
|
||||
{
|
||||
$this->m_sCode = $sCode;
|
||||
$this->m_aParams = $aParams;
|
||||
$this->ConsistencyCheck();
|
||||
}
|
||||
|
||||
public function OverloadParams($aParams)
|
||||
{
|
||||
foreach ($aParams as $sParam => $value)
|
||||
{
|
||||
if (!array_key_exists($sParam, $this->m_aParams))
|
||||
{
|
||||
throw new CoreException("Unknown attribute definition parameter '$sParam', please select a value in {".implode(", ", $this->m_aParams)."}");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->m_aParams[$sParam] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// to be overloaded
|
||||
static protected function ListExpectedParams()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
private function ConsistencyCheck()
|
||||
{
|
||||
// Check that any mandatory param has been specified
|
||||
//
|
||||
$aExpectedParams = $this->ListExpectedParams();
|
||||
foreach($aExpectedParams as $sParamName)
|
||||
{
|
||||
if (!array_key_exists($sParamName, $this->m_aParams))
|
||||
{
|
||||
$aBacktrace = debug_backtrace();
|
||||
$sTargetClass = $aBacktrace[2]["class"];
|
||||
$sCodeInfo = $aBacktrace[1]["file"]." - ".$aBacktrace[1]["line"];
|
||||
throw new CoreException("ERROR missing parameter '$sParamName' in ".get_class($this)." declaration for class $sTargetClass ($sCodeInfo)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function GetCode() {return $this->m_sCode;}
|
||||
abstract public function GetLabel();
|
||||
abstract public function GetValuesDef();
|
||||
|
||||
// returns an array of opcode=>oplabel (e.g. "differs from")
|
||||
abstract public function GetOperators();
|
||||
// returns an opcode
|
||||
abstract public function GetLooseOperator();
|
||||
abstract public function GetSQLExpressions();
|
||||
|
||||
// Wrapper - no need for overloading this one
|
||||
public function GetOpDescription($sOpCode)
|
||||
{
|
||||
$aOperators = $this->GetOperators();
|
||||
if (!array_key_exists($sOpCode, $aOperators))
|
||||
{
|
||||
throw new CoreException("Unknown operator '$sOpCode'");
|
||||
}
|
||||
|
||||
return $aOperators[$sOpCode];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Match against the object unique identifier
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class FilterPrivateKey extends FilterDefinition
|
||||
{
|
||||
static protected function ListExpectedParams()
|
||||
{
|
||||
return array_merge(parent::ListExpectedParams(), array("id_field"));
|
||||
}
|
||||
|
||||
public function GetType() {return "PrivateKey";}
|
||||
public function GetTypeDesc() {return "Match against object identifier";}
|
||||
|
||||
public function GetLabel()
|
||||
{
|
||||
return "Object Private Key";
|
||||
}
|
||||
|
||||
public function GetValuesDef()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function GetOperators()
|
||||
{
|
||||
return array(
|
||||
"="=>"equals",
|
||||
"!="=>"differs from",
|
||||
"IN"=>"in",
|
||||
"NOTIN"=>"not in"
|
||||
);
|
||||
}
|
||||
public function GetLooseOperator()
|
||||
{
|
||||
return "IN";
|
||||
}
|
||||
|
||||
public function GetSQLExpressions()
|
||||
{
|
||||
return array(
|
||||
'' => $this->Get("id_field"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Match against an existing attribute (the attribute type will determine the available operators)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class FilterFromAttribute extends FilterDefinition
|
||||
{
|
||||
static protected function ListExpectedParams()
|
||||
{
|
||||
return array_merge(parent::ListExpectedParams(), array("refattribute"));
|
||||
}
|
||||
|
||||
public function __construct($oRefAttribute, $aParam = array())
|
||||
{
|
||||
// In this very specific case, the code is the one of the attribute
|
||||
// (this to get a very very simple syntax upon declaration)
|
||||
$aParam["refattribute"] = $oRefAttribute;
|
||||
parent::__construct($oRefAttribute->GetCode(), $aParam);
|
||||
}
|
||||
|
||||
public function GetType() {return "Basic";}
|
||||
public function GetTypeDesc() {return "Match against field contents";}
|
||||
|
||||
public function __GetRefAttribute() // for checking purposes only !!!
|
||||
{
|
||||
return $oAttDef = $this->Get("refattribute");
|
||||
}
|
||||
|
||||
public function GetLabel()
|
||||
{
|
||||
$oAttDef = $this->Get("refattribute");
|
||||
return $oAttDef->GetLabel();
|
||||
}
|
||||
|
||||
public function GetValuesDef()
|
||||
{
|
||||
$oAttDef = $this->Get("refattribute");
|
||||
return $oAttDef->GetValuesDef();
|
||||
}
|
||||
|
||||
public function GetAllowedValues($aArgs = array(), $sBeginsWith = '')
|
||||
{
|
||||
$oAttDef = $this->Get("refattribute");
|
||||
return $oAttDef->GetAllowedValues($aArgs, $sBeginsWith);
|
||||
}
|
||||
|
||||
public function GetOperators()
|
||||
{
|
||||
$oAttDef = $this->Get("refattribute");
|
||||
return $oAttDef->GetBasicFilterOperators();
|
||||
}
|
||||
public function GetLooseOperator()
|
||||
{
|
||||
$oAttDef = $this->Get("refattribute");
|
||||
return $oAttDef->GetBasicFilterLooseOperator();
|
||||
}
|
||||
|
||||
public function GetSQLExpressions()
|
||||
{
|
||||
$oAttDef = $this->Get("refattribute");
|
||||
return $oAttDef->GetSQLExpressions();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
2929
core/metamodel.class.php
Normal file
2929
core/metamodel.class.php
Normal file
File diff suppressed because it is too large
Load Diff
3
core/oql/build.cmd
Normal file
3
core/oql/build.cmd
Normal file
@@ -0,0 +1,3 @@
|
||||
c:\itop\php-5.2.3\php.exe -q "C:\itop\PHP-5.2.3\PEAR\PHP\LexerGenerator\cli.php" oql-lexer.plex
|
||||
c:\itop\php-5.2.3\php.exe -q "C:\itop\PHP-5.2.3\PEAR\PHP\ParserGenerator\cli.php" oql-parser.y
|
||||
pause
|
||||
564
core/oql/oql-lexer.php
Normal file
564
core/oql/oql-lexer.php
Normal file
@@ -0,0 +1,564 @@
|
||||
<?php
|
||||
|
||||
// Notes (from the source file: oql-lexer.plex) - Romain
|
||||
//
|
||||
// The strval rule is a little bit cryptic.
|
||||
// This is due to both a bug in the lexer generator and the complexity of our need
|
||||
// The rule means: either a quoted string with ", or a quoted string with '
|
||||
// literal " (resp. ') must be escaped by a \
|
||||
// \ must be escaped by an additional \
|
||||
//
|
||||
// Here are the issues and limitation found in the lexer generator:
|
||||
// * Matching simple quotes is an issue, because regexp are not correctly escaped (and the ESC code is escaped itself)
|
||||
// Workaround: insert '.chr(39).' which will be a real ' in the end
|
||||
// * Matching an alternate regexp is an issue because you must specify "|^...."
|
||||
// and the regexp parser will not accept that syntax
|
||||
// Workaround: insert '.chr(94).' which will be a real ^
|
||||
//
|
||||
// Let's analyze an overview of the regexp, we have
|
||||
// 1) The strval rule in the lexer definition
|
||||
// /"([^\\"]|\\"|\\\\)*"|'.chr(94).chr(39).'([^\\'.chr(39).']|\\'.chr(39).'|\\\\)*'.chr(39).'/
|
||||
// 2) Becomes the php expression in the lexer
|
||||
// (note the escaped double quotes, hopefully having no effect, but showing where the issue is!)
|
||||
// $myRegexp = '/^\"([^\\\\\"]|\\\\\"|\\\\\\\\)*\"|'.chr(94).chr(39).'([^\\\\'.chr(39).']|\\\\'.chr(39).'|\\\\\\\\)*'.chr(39).'/';
|
||||
//
|
||||
// To be fixed in LexerGenerator/Parser.y, in doLongestMatch (doFirstMatch is ok)
|
||||
//
|
||||
//
|
||||
// Now, let's explain how the regexp has been designed.
|
||||
// Here is a simplified version, dealing with simple quotes, and based on the assumption that the lexer generator has been fixed!
|
||||
// The strval rule in the lexer definition
|
||||
// /'([^\\']*(\\')*(\\\\)*)*'/
|
||||
// This means anything containing \\ or \' or any other char but a standalone ' or \
|
||||
// This means ' or \ could not be found without a preceding \
|
||||
//
|
||||
class OQLLexerRaw
|
||||
{
|
||||
protected $data; // input string
|
||||
public $token; // token id
|
||||
public $value; // token string representation
|
||||
protected $line; // current line
|
||||
protected $count; // current column
|
||||
|
||||
function __construct($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->count = 0;
|
||||
$this->line = 1;
|
||||
}
|
||||
|
||||
|
||||
private $_yy_state = 1;
|
||||
private $_yy_stack = array();
|
||||
|
||||
function yylex()
|
||||
{
|
||||
return $this->{'yylex' . $this->_yy_state}();
|
||||
}
|
||||
|
||||
function yypushstate($state)
|
||||
{
|
||||
array_push($this->_yy_stack, $this->_yy_state);
|
||||
$this->_yy_state = $state;
|
||||
}
|
||||
|
||||
function yypopstate()
|
||||
{
|
||||
$this->_yy_state = array_pop($this->_yy_stack);
|
||||
}
|
||||
|
||||
function yybegin($state)
|
||||
{
|
||||
$this->_yy_state = $state;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function yylex1()
|
||||
{
|
||||
if ($this->count >= strlen($this->data)) {
|
||||
return false; // end of input
|
||||
}
|
||||
do {
|
||||
$rules = array(
|
||||
'/^[ \t\n\r]+/',
|
||||
'/^SELECT/',
|
||||
'/^FROM/',
|
||||
'/^AS/',
|
||||
'/^WHERE/',
|
||||
'/^JOIN/',
|
||||
'/^ON/',
|
||||
'/^\//',
|
||||
'/^\\*/',
|
||||
'/^\\+/',
|
||||
'/^-/',
|
||||
'/^AND/',
|
||||
'/^OR/',
|
||||
'/^,/',
|
||||
'/^\\(/',
|
||||
'/^\\)/',
|
||||
'/^=/',
|
||||
'/^!=/',
|
||||
'/^>/',
|
||||
'/^</',
|
||||
'/^>=/',
|
||||
'/^<=/',
|
||||
'/^LIKE/',
|
||||
'/^NOT LIKE/',
|
||||
'/^IN/',
|
||||
'/^NOT IN/',
|
||||
'/^INTERVAL/',
|
||||
'/^IF/',
|
||||
'/^ELT/',
|
||||
'/^COALESCE/',
|
||||
'/^CONCAT/',
|
||||
'/^SUBSTR/',
|
||||
'/^TRIM/',
|
||||
'/^DATE/',
|
||||
'/^DATE_FORMAT/',
|
||||
'/^CURRENT_DATE/',
|
||||
'/^NOW/',
|
||||
'/^TIME/',
|
||||
'/^TO_DAYS/',
|
||||
'/^FROM_DAYS/',
|
||||
'/^YEAR/',
|
||||
'/^MONTH/',
|
||||
'/^DAY/',
|
||||
'/^HOUR/',
|
||||
'/^MINUTE/',
|
||||
'/^SECOND/',
|
||||
'/^DATE_ADD/',
|
||||
'/^DATE_SUB/',
|
||||
'/^ROUND/',
|
||||
'/^FLOOR/',
|
||||
'/^INET_ATON/',
|
||||
'/^INET_NTOA/',
|
||||
'/^[0-9]+|0x[0-9a-fA-F]+/',
|
||||
'/^\"([^\\\\\"]|\\\\\"|\\\\\\\\)*\"|'.chr(94).chr(39).'([^\\\\'.chr(39).']|\\\\'.chr(39).'|\\\\\\\\)*'.chr(39).'/',
|
||||
'/^([_a-zA-Z][_a-zA-Z0-9]*|`[^`]+`)/',
|
||||
'/^:([_a-zA-Z][_a-zA-Z0-9]*->[_a-zA-Z][_a-zA-Z0-9]*|[_a-zA-Z][_a-zA-Z0-9]*)/',
|
||||
'/^\\./',
|
||||
);
|
||||
$match = false;
|
||||
foreach ($rules as $index => $rule) {
|
||||
if (preg_match($rule, substr($this->data, $this->count), $yymatches)) {
|
||||
if ($match) {
|
||||
if (strlen($yymatches[0]) > strlen($match[0][0])) {
|
||||
$match = array($yymatches, $index); // matches, token
|
||||
}
|
||||
} else {
|
||||
$match = array($yymatches, $index);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$match) {
|
||||
throw new Exception('Unexpected input at line' . $this->line .
|
||||
': ' . $this->data[$this->count]);
|
||||
}
|
||||
$this->token = $match[1];
|
||||
$this->value = $match[0][0];
|
||||
$yysubmatches = $match[0];
|
||||
array_shift($yysubmatches);
|
||||
if (!$yysubmatches) {
|
||||
$yysubmatches = array();
|
||||
}
|
||||
$r = $this->{'yy_r1_' . $this->token}($yysubmatches);
|
||||
if ($r === null) {
|
||||
$this->count += strlen($this->value);
|
||||
$this->line += substr_count($this->value, "\n");
|
||||
// accept this token
|
||||
return true;
|
||||
} elseif ($r === true) {
|
||||
// we have changed state
|
||||
// process this token in the new state
|
||||
return $this->yylex();
|
||||
} elseif ($r === false) {
|
||||
$this->count += strlen($this->value);
|
||||
$this->line += substr_count($this->value, "\n");
|
||||
if ($this->count >= strlen($this->data)) {
|
||||
return false; // end of input
|
||||
}
|
||||
// skip this token
|
||||
continue;
|
||||
} else {
|
||||
$yy_yymore_patterns = array_slice($rules, $this->token, true);
|
||||
// yymore is needed
|
||||
do {
|
||||
if (!isset($yy_yymore_patterns[$this->token])) {
|
||||
throw new Exception('cannot do yymore for the last token');
|
||||
}
|
||||
$match = false;
|
||||
foreach ($yy_yymore_patterns[$this->token] as $index => $rule) {
|
||||
if (preg_match('/' . $rule . '/',
|
||||
substr($this->data, $this->count), $yymatches)) {
|
||||
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
|
||||
if ($match) {
|
||||
if (strlen($yymatches[0]) > strlen($match[0][0])) {
|
||||
$match = array($yymatches, $index); // matches, token
|
||||
}
|
||||
} else {
|
||||
$match = array($yymatches, $index);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$match) {
|
||||
throw new Exception('Unexpected input at line' . $this->line .
|
||||
': ' . $this->data[$this->count]);
|
||||
}
|
||||
$this->token = $match[1];
|
||||
$this->value = $match[0][0];
|
||||
$yysubmatches = $match[0];
|
||||
array_shift($yysubmatches);
|
||||
if (!$yysubmatches) {
|
||||
$yysubmatches = array();
|
||||
}
|
||||
$this->line = substr_count($this->value, "\n");
|
||||
$r = $this->{'yy_r1_' . $this->token}();
|
||||
} while ($r !== null || !$r);
|
||||
if ($r === true) {
|
||||
// we have changed state
|
||||
// process this token in the new state
|
||||
return $this->yylex();
|
||||
} else {
|
||||
// accept
|
||||
$this->count += strlen($this->value);
|
||||
$this->line += substr_count($this->value, "\n");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} while (true);
|
||||
|
||||
} // end function
|
||||
|
||||
function yy_r1_0($yy_subpatterns)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
function yy_r1_1($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::SELECT;
|
||||
}
|
||||
function yy_r1_2($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::FROM;
|
||||
}
|
||||
function yy_r1_3($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::AS_ALIAS;
|
||||
}
|
||||
function yy_r1_4($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::WHERE;
|
||||
}
|
||||
function yy_r1_5($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::JOIN;
|
||||
}
|
||||
function yy_r1_6($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::ON;
|
||||
}
|
||||
function yy_r1_7($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::MATH_DIV;
|
||||
}
|
||||
function yy_r1_8($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::MATH_MULT;
|
||||
}
|
||||
function yy_r1_9($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::MATH_PLUS;
|
||||
}
|
||||
function yy_r1_10($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::MATH_MINUS;
|
||||
}
|
||||
function yy_r1_11($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::LOG_AND;
|
||||
}
|
||||
function yy_r1_12($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::LOG_OR;
|
||||
}
|
||||
function yy_r1_13($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::COMA;
|
||||
}
|
||||
function yy_r1_14($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::PAR_OPEN;
|
||||
}
|
||||
function yy_r1_15($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::PAR_CLOSE;
|
||||
}
|
||||
function yy_r1_16($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::EQ;
|
||||
}
|
||||
function yy_r1_17($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::NOT_EQ;
|
||||
}
|
||||
function yy_r1_18($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::GT;
|
||||
}
|
||||
function yy_r1_19($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::LT;
|
||||
}
|
||||
function yy_r1_20($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::GE;
|
||||
}
|
||||
function yy_r1_21($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::LE;
|
||||
}
|
||||
function yy_r1_22($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::LIKE;
|
||||
}
|
||||
function yy_r1_23($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::NOT_LIKE;
|
||||
}
|
||||
function yy_r1_24($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::IN;
|
||||
}
|
||||
function yy_r1_25($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::NOT_IN;
|
||||
}
|
||||
function yy_r1_26($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::INTERVAL;
|
||||
}
|
||||
function yy_r1_27($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_IF;
|
||||
}
|
||||
function yy_r1_28($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_ELT;
|
||||
}
|
||||
function yy_r1_29($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_COALESCE;
|
||||
}
|
||||
function yy_r1_30($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_CONCAT;
|
||||
}
|
||||
function yy_r1_31($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_SUBSTR;
|
||||
}
|
||||
function yy_r1_32($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_TRIM;
|
||||
}
|
||||
function yy_r1_33($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_DATE;
|
||||
}
|
||||
function yy_r1_34($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_DATE_FORMAT;
|
||||
}
|
||||
function yy_r1_35($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_CURRENT_DATE;
|
||||
}
|
||||
function yy_r1_36($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_NOW;
|
||||
}
|
||||
function yy_r1_37($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_TIME;
|
||||
}
|
||||
function yy_r1_38($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_TO_DAYS;
|
||||
}
|
||||
function yy_r1_39($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_FROM_DAYS;
|
||||
}
|
||||
function yy_r1_40($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_YEAR;
|
||||
}
|
||||
function yy_r1_41($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_MONTH;
|
||||
}
|
||||
function yy_r1_42($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_DAY;
|
||||
}
|
||||
function yy_r1_43($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_HOUR;
|
||||
}
|
||||
function yy_r1_44($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_MINUTE;
|
||||
}
|
||||
function yy_r1_45($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_SECOND;
|
||||
}
|
||||
function yy_r1_46($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_DATE_ADD;
|
||||
}
|
||||
function yy_r1_47($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_DATE_SUB;
|
||||
}
|
||||
function yy_r1_48($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_ROUND;
|
||||
}
|
||||
function yy_r1_49($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_FLOOR;
|
||||
}
|
||||
function yy_r1_50($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_INET_ATON;
|
||||
}
|
||||
function yy_r1_51($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::F_INET_NTOA;
|
||||
}
|
||||
function yy_r1_52($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::NUMVAL;
|
||||
}
|
||||
function yy_r1_53($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::STRVAL;
|
||||
}
|
||||
function yy_r1_54($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::NAME;
|
||||
}
|
||||
function yy_r1_55($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::VARNAME;
|
||||
}
|
||||
function yy_r1_56($yy_subpatterns)
|
||||
{
|
||||
|
||||
$this->token = OQLParser::DOT;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
define('UNEXPECTED_INPUT_AT_LINE', 'Unexpected input at line');
|
||||
|
||||
class OQLLexerException extends OQLException
|
||||
{
|
||||
public function __construct($sInput, $iLine, $iCol, $sUnexpected)
|
||||
{
|
||||
parent::__construct("Syntax error", $sInput, $iLine, $iCol, $sUnexpected);
|
||||
}
|
||||
}
|
||||
|
||||
class OQLLexer extends OQLLexerRaw
|
||||
{
|
||||
public function getTokenPos()
|
||||
{
|
||||
return max(0, $this->count - strlen($this->value));
|
||||
}
|
||||
|
||||
function yylex()
|
||||
{
|
||||
try
|
||||
{
|
||||
return parent::yylex();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$sMessage = $e->getMessage();
|
||||
if (substr($sMessage, 0, strlen(UNEXPECTED_INPUT_AT_LINE)) == UNEXPECTED_INPUT_AT_LINE)
|
||||
{
|
||||
$sLineAndChar = substr($sMessage, strlen(UNEXPECTED_INPUT_AT_LINE));
|
||||
if (preg_match('#^([0-9]+): (.+)$#', $sLineAndChar, $aMatches))
|
||||
{
|
||||
$iLine = $aMatches[1];
|
||||
$sUnexpected = $aMatches[2];
|
||||
throw new OQLLexerException($this->data, $iLine, $this->count, $sUnexpected);
|
||||
}
|
||||
}
|
||||
// Default: forward the exception
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
333
core/oql/oql-lexer.plex
Normal file
333
core/oql/oql-lexer.plex
Normal file
@@ -0,0 +1,333 @@
|
||||
<?php
|
||||
|
||||
// Notes (from the source file: oql-lexer.plex) - Romain
|
||||
//
|
||||
// The strval rule is a little bit cryptic.
|
||||
// This is due to both a bug in the lexer generator and the complexity of our need
|
||||
// The rule means: either a quoted string with ", or a quoted string with '
|
||||
// literal " (resp. ') must be escaped by a \
|
||||
// \ must be escaped by an additional \
|
||||
//
|
||||
// Here are the issues and limitation found in the lexer generator:
|
||||
// * Matching simple quotes is an issue, because regexp are not correctly escaped (and the ESC code is escaped itself)
|
||||
// Workaround: insert '.chr(39).' which will be a real ' in the end
|
||||
// * Matching an alternate regexp is an issue because you must specify "|^...."
|
||||
// and the regexp parser will not accept that syntax
|
||||
// Workaround: insert '.chr(94).' which will be a real ^
|
||||
//
|
||||
// Let's analyze an overview of the regexp, we have
|
||||
// 1) The strval rule in the lexer definition
|
||||
// /"([^\\"]|\\"|\\\\)*"|'.chr(94).chr(39).'([^\\'.chr(39).']|\\'.chr(39).'|\\\\)*'.chr(39).'/
|
||||
// 2) Becomes the php expression in the lexer
|
||||
// (note the escaped double quotes, hopefully having no effect, but showing where the issue is!)
|
||||
// $myRegexp = '/^\"([^\\\\\"]|\\\\\"|\\\\\\\\)*\"|'.chr(94).chr(39).'([^\\\\'.chr(39).']|\\\\'.chr(39).'|\\\\\\\\)*'.chr(39).'/';
|
||||
//
|
||||
// To be fixed in LexerGenerator/Parser.y, in doLongestMatch (doFirstMatch is ok)
|
||||
//
|
||||
//
|
||||
// Now, let's explain how the regexp has been designed.
|
||||
// Here is a simplified version, dealing with simple quotes, and based on the assumption that the lexer generator has been fixed!
|
||||
// The strval rule in the lexer definition
|
||||
// /'([^\\']*(\\')*(\\\\)*)*'/
|
||||
// This means anything containing \\ or \' or any other char but a standalone ' or \
|
||||
// This means ' or \ could not be found without a preceding \
|
||||
//
|
||||
class OQLLexerRaw
|
||||
{
|
||||
protected $data; // input string
|
||||
public $token; // token id
|
||||
public $value; // token string representation
|
||||
protected $line; // current line
|
||||
protected $count; // current column
|
||||
|
||||
function __construct($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->count = 0;
|
||||
$this->line = 1;
|
||||
}
|
||||
|
||||
/*!lex2php
|
||||
%input $this->data
|
||||
%counter $this->count
|
||||
%token $this->token
|
||||
%value $this->value
|
||||
%line $this->line
|
||||
%matchlongest 1
|
||||
whitespace = /[ \t\n\r]+/
|
||||
select = "SELECT"
|
||||
from = "FROM"
|
||||
as_alias = "AS"
|
||||
where = "WHERE"
|
||||
join = "JOIN"
|
||||
on = "ON"
|
||||
coma = ","
|
||||
par_open = "("
|
||||
par_close = ")"
|
||||
math_div = "/"
|
||||
math_mult = "*"
|
||||
math_plus = "+"
|
||||
math_minus = "-"
|
||||
log_and = "AND"
|
||||
log_or = "OR"
|
||||
eq = "="
|
||||
not_eq = "!="
|
||||
gt = ">"
|
||||
lt = "<"
|
||||
ge = ">="
|
||||
le = "<="
|
||||
like = "LIKE"
|
||||
not_like = "NOT LIKE"
|
||||
in = "IN"
|
||||
not_in = "NOT IN"
|
||||
interval = "INTERVAL"
|
||||
f_if = "IF"
|
||||
f_elt = "ELT"
|
||||
f_coalesce = "COALESCE"
|
||||
f_concat = "CONCAT"
|
||||
f_substr = "SUBSTR"
|
||||
f_trim = "TRIM"
|
||||
f_date = "DATE"
|
||||
f_date_format = "DATE_FORMAT"
|
||||
f_current_date = "CURRENT_DATE"
|
||||
f_now = "NOW"
|
||||
f_time = "TIME"
|
||||
f_to_days = "TO_DAYS"
|
||||
f_from_days = "FROM_DAYS"
|
||||
f_year = "YEAR"
|
||||
f_month = "MONTH"
|
||||
f_day = "DAY"
|
||||
f_hour = "HOUR"
|
||||
f_minute = "MINUTE"
|
||||
f_second = "SECOND"
|
||||
f_date_add = "DATE_ADD"
|
||||
f_date_sub = "DATE_SUB"
|
||||
f_round = "ROUND"
|
||||
f_floor = "FLOOR"
|
||||
f_inet_aton = "INET_ATON"
|
||||
f_inet_ntoa = "INET_NTOA"
|
||||
numval = /[0-9]+|0x[0-9a-fA-F]+/
|
||||
strval = /"([^\\"]|\\"|\\\\)*"|'.chr(94).chr(39).'([^\\'.chr(39).']|\\'.chr(39).'|\\\\)*'.chr(39).'/
|
||||
name = /([_a-zA-Z][_a-zA-Z0-9]*|`[^`]+`)/
|
||||
varname = /:([_a-zA-Z][_a-zA-Z0-9]*->[_a-zA-Z][_a-zA-Z0-9]*|[_a-zA-Z][_a-zA-Z0-9]*)/
|
||||
dot = "."
|
||||
*/
|
||||
|
||||
/*!lex2php
|
||||
whitespace {
|
||||
return false;
|
||||
}
|
||||
select {
|
||||
$this->token = OQLParser::SELECT;
|
||||
}
|
||||
from {
|
||||
$this->token = OQLParser::FROM;
|
||||
}
|
||||
as_alias {
|
||||
$this->token = OQLParser::AS_ALIAS;
|
||||
}
|
||||
where {
|
||||
$this->token = OQLParser::WHERE;
|
||||
}
|
||||
join {
|
||||
$this->token = OQLParser::JOIN;
|
||||
}
|
||||
on {
|
||||
$this->token = OQLParser::ON;
|
||||
}
|
||||
math_div {
|
||||
$this->token = OQLParser::MATH_DIV;
|
||||
}
|
||||
math_mult {
|
||||
$this->token = OQLParser::MATH_MULT;
|
||||
}
|
||||
math_plus {
|
||||
$this->token = OQLParser::MATH_PLUS;
|
||||
}
|
||||
math_minus {
|
||||
$this->token = OQLParser::MATH_MINUS;
|
||||
}
|
||||
log_and {
|
||||
$this->token = OQLParser::LOG_AND;
|
||||
}
|
||||
log_or {
|
||||
$this->token = OQLParser::LOG_OR;
|
||||
}
|
||||
coma {
|
||||
$this->token = OQLParser::COMA;
|
||||
}
|
||||
par_open {
|
||||
$this->token = OQLParser::PAR_OPEN;
|
||||
}
|
||||
par_close {
|
||||
$this->token = OQLParser::PAR_CLOSE;
|
||||
}
|
||||
eq {
|
||||
$this->token = OQLParser::EQ;
|
||||
}
|
||||
not_eq {
|
||||
$this->token = OQLParser::NOT_EQ;
|
||||
}
|
||||
gt {
|
||||
$this->token = OQLParser::GT;
|
||||
}
|
||||
lt {
|
||||
$this->token = OQLParser::LT;
|
||||
}
|
||||
ge {
|
||||
$this->token = OQLParser::GE;
|
||||
}
|
||||
le {
|
||||
$this->token = OQLParser::LE;
|
||||
}
|
||||
like {
|
||||
$this->token = OQLParser::LIKE;
|
||||
}
|
||||
not_like {
|
||||
$this->token = OQLParser::NOT_LIKE;
|
||||
}
|
||||
in {
|
||||
$this->token = OQLParser::IN;
|
||||
}
|
||||
not_in {
|
||||
$this->token = OQLParser::NOT_IN;
|
||||
}
|
||||
interval {
|
||||
$this->token = OQLParser::INTERVAL;
|
||||
}
|
||||
f_if {
|
||||
$this->token = OQLParser::F_IF;
|
||||
}
|
||||
f_elt {
|
||||
$this->token = OQLParser::F_ELT;
|
||||
}
|
||||
f_coalesce {
|
||||
$this->token = OQLParser::F_COALESCE;
|
||||
}
|
||||
f_concat {
|
||||
$this->token = OQLParser::F_CONCAT;
|
||||
}
|
||||
f_substr {
|
||||
$this->token = OQLParser::F_SUBSTR;
|
||||
}
|
||||
f_trim {
|
||||
$this->token = OQLParser::F_TRIM;
|
||||
}
|
||||
f_date {
|
||||
$this->token = OQLParser::F_DATE;
|
||||
}
|
||||
f_date_format {
|
||||
$this->token = OQLParser::F_DATE_FORMAT;
|
||||
}
|
||||
f_current_date {
|
||||
$this->token = OQLParser::F_CURRENT_DATE;
|
||||
}
|
||||
f_now {
|
||||
$this->token = OQLParser::F_NOW;
|
||||
}
|
||||
f_time {
|
||||
$this->token = OQLParser::F_TIME;
|
||||
}
|
||||
f_to_days {
|
||||
$this->token = OQLParser::F_TO_DAYS;
|
||||
}
|
||||
f_from_days {
|
||||
$this->token = OQLParser::F_FROM_DAYS;
|
||||
}
|
||||
f_year {
|
||||
$this->token = OQLParser::F_YEAR;
|
||||
}
|
||||
f_month {
|
||||
$this->token = OQLParser::F_MONTH;
|
||||
}
|
||||
f_day {
|
||||
$this->token = OQLParser::F_DAY;
|
||||
}
|
||||
f_hour {
|
||||
$this->token = OQLParser::F_HOUR;
|
||||
}
|
||||
f_minute {
|
||||
$this->token = OQLParser::F_MINUTE;
|
||||
}
|
||||
f_second {
|
||||
$this->token = OQLParser::F_SECOND;
|
||||
}
|
||||
f_date_add {
|
||||
$this->token = OQLParser::F_DATE_ADD;
|
||||
}
|
||||
f_date_sub {
|
||||
$this->token = OQLParser::F_DATE_SUB;
|
||||
}
|
||||
f_round {
|
||||
$this->token = OQLParser::F_ROUND;
|
||||
}
|
||||
f_floor {
|
||||
$this->token = OQLParser::F_FLOOR;
|
||||
}
|
||||
f_inet_aton {
|
||||
$this->token = OQLParser::F_INET_ATON;
|
||||
}
|
||||
f_inet_ntoa {
|
||||
$this->token = OQLParser::F_INET_NTOA;
|
||||
}
|
||||
numval {
|
||||
$this->token = OQLParser::NUMVAL;
|
||||
}
|
||||
strval {
|
||||
$this->token = OQLParser::STRVAL;
|
||||
}
|
||||
name {
|
||||
$this->token = OQLParser::NAME;
|
||||
}
|
||||
varname {
|
||||
$this->token = OQLParser::VARNAME;
|
||||
}
|
||||
dot {
|
||||
$this->token = OQLParser::DOT;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
define('UNEXPECTED_INPUT_AT_LINE', 'Unexpected input at line');
|
||||
|
||||
class OQLLexerException extends OQLException
|
||||
{
|
||||
public function __construct($sInput, $iLine, $iCol, $sUnexpected)
|
||||
{
|
||||
parent::__construct("Syntax error", $sInput, $iLine, $iCol, $sUnexpected);
|
||||
}
|
||||
}
|
||||
|
||||
class OQLLexer extends OQLLexerRaw
|
||||
{
|
||||
public function getTokenPos()
|
||||
{
|
||||
return max(0, $this->count - strlen($this->value));
|
||||
}
|
||||
|
||||
function yylex()
|
||||
{
|
||||
try
|
||||
{
|
||||
return parent::yylex();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$sMessage = $e->getMessage();
|
||||
if (substr($sMessage, 0, strlen(UNEXPECTED_INPUT_AT_LINE)) == UNEXPECTED_INPUT_AT_LINE)
|
||||
{
|
||||
$sLineAndChar = substr($sMessage, strlen(UNEXPECTED_INPUT_AT_LINE));
|
||||
if (preg_match('#^([0-9]+): (.+)$#', $sLineAndChar, $aMatches))
|
||||
{
|
||||
$iLine = $aMatches[1];
|
||||
$sUnexpected = $aMatches[2];
|
||||
throw new OQLLexerException($this->data, $iLine, $this->count, $sUnexpected);
|
||||
}
|
||||
}
|
||||
// Default: forward the exception
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
1712
core/oql/oql-parser.php
Normal file
1712
core/oql/oql-parser.php
Normal file
File diff suppressed because it is too large
Load Diff
268
core/oql/oql-parser.y
Normal file
268
core/oql/oql-parser.y
Normal file
@@ -0,0 +1,268 @@
|
||||
|
||||
/*
|
||||
|
||||
This is a LALR(1) grammar
|
||||
(seek for Lemon grammar to get some documentation from the Net)
|
||||
That doc was helpful: http://www.hwaci.com/sw/lemon/lemon.html
|
||||
|
||||
To handle operators precedence we could have used the %left directive
|
||||
(we took another option, because that one was discovered right after...
|
||||
which option is the best for us?)
|
||||
Example:
|
||||
%left LOG_AND.
|
||||
%left LOG_OR.
|
||||
%nonassoc EQ NE GT GE LT LE.
|
||||
%left PLUS MINUS.
|
||||
%left TIMES DIVIDE MOD.
|
||||
%right EXP NOT.
|
||||
|
||||
TODO : solve the 2 remaining shift-reduce conflicts (JOIN)
|
||||
|
||||
*/
|
||||
|
||||
%name OQLParser_
|
||||
%declare_class {class OQLParserRaw}
|
||||
%syntax_error {
|
||||
throw new OQLParserException($this->m_sSourceQuery, $this->m_iLine, $this->m_iCol, $this->tokenName($yymajor), $TOKEN);
|
||||
}
|
||||
|
||||
result ::= query(X). { $this->my_result = X; }
|
||||
result ::= condition(X). { $this->my_result = X; }
|
||||
|
||||
query(A) ::= SELECT class_name(X) join_statement(J) where_statement(W). {
|
||||
A = new OqlObjectQuery(X, X, W, J);
|
||||
}
|
||||
query(A) ::= SELECT class_name(X) AS_ALIAS class_name(Y) join_statement(J) where_statement(W). {
|
||||
A = new OqlObjectQuery(X, Y, W, J);
|
||||
}
|
||||
|
||||
/*
|
||||
query(A) ::= SELECT field_id(E) FROM class_name(X) join_statement(J) where_statement(W). {
|
||||
A = new OqlValueSetQuery(E, X, X, W, J);
|
||||
}
|
||||
query(A) ::= SELECT field_id(E) FROM class_name(X) AS_ALIAS class_name(Y) join_statement(J) where_statement(W). {
|
||||
A = new OqlValueSetQuery(E, X, Y, W, J);
|
||||
}
|
||||
*/
|
||||
|
||||
where_statement(A) ::= WHERE condition(C). { A = C;}
|
||||
where_statement(A) ::= . { A = null;}
|
||||
|
||||
join_statement(A) ::= join_item(J) join_statement(S). {
|
||||
// insert the join statement on top of the existing list
|
||||
array_unshift(S, J);
|
||||
// and return the updated array
|
||||
A = S;
|
||||
}
|
||||
join_statement(A) ::= join_item(J). {
|
||||
A = Array(J);
|
||||
}
|
||||
join_statement(A) ::= . { A = null;}
|
||||
|
||||
join_item(A) ::= JOIN class_name(X) AS_ALIAS class_name(Y) ON join_condition(C).
|
||||
{
|
||||
// create an array with one single item
|
||||
A = new OqlJoinSpec(X, Y, C);
|
||||
}
|
||||
join_item(A) ::= JOIN class_name(X) ON join_condition(C).
|
||||
{
|
||||
// create an array with one single item
|
||||
A = new OqlJoinSpec(X, X, C);
|
||||
}
|
||||
|
||||
join_condition(A) ::= field_id(X) EQ field_id(Y). { A = new BinaryOqlExpression(X, '=', Y); }
|
||||
|
||||
condition(A) ::= expression_prio4(X). { A = X; }
|
||||
|
||||
expression_basic(A) ::= scalar(X). { A = X; }
|
||||
expression_basic(A) ::= field_id(X). { A = X; }
|
||||
expression_basic(A) ::= var_name(X). { A = X; }
|
||||
expression_basic(A) ::= func_name(X) PAR_OPEN arg_list(Y) PAR_CLOSE. { A = new FunctionOqlExpression(X, Y); }
|
||||
expression_basic(A) ::= PAR_OPEN expression_prio4(X) PAR_CLOSE. { A = X; }
|
||||
expression_basic(A) ::= expression_basic(X) list_operator(Y) list(Z). { A = new BinaryOqlExpression(X, Y, Z); }
|
||||
|
||||
expression_prio1(A) ::= expression_basic(X). { A = X; }
|
||||
expression_prio1(A) ::= expression_prio1(X) operator1(Y) expression_basic(Z). { A = new BinaryOqlExpression(X, Y, Z); }
|
||||
|
||||
expression_prio2(A) ::= expression_prio1(X). { A = X; }
|
||||
expression_prio2(A) ::= expression_prio2(X) operator2(Y) expression_prio1(Z). { A = new BinaryOqlExpression(X, Y, Z); }
|
||||
|
||||
expression_prio3(A) ::= expression_prio2(X). { A = X; }
|
||||
expression_prio3(A) ::= expression_prio3(X) operator3(Y) expression_prio2(Z). { A = new BinaryOqlExpression(X, Y, Z); }
|
||||
|
||||
expression_prio4(A) ::= expression_prio3(X). { A = X; }
|
||||
expression_prio4(A) ::= expression_prio4(X) operator4(Y) expression_prio3(Z). { A = new BinaryOqlExpression(X, Y, Z); }
|
||||
|
||||
|
||||
list(A) ::= PAR_OPEN scalar_list(X) PAR_CLOSE. {
|
||||
A = new ListOqlExpression(X);
|
||||
}
|
||||
scalar_list(A) ::= scalar(X). {
|
||||
A = array(X);
|
||||
}
|
||||
scalar_list(A) ::= scalar_list(L) COMA scalar(X). {
|
||||
array_push(L, X);
|
||||
A = L;
|
||||
}
|
||||
|
||||
arg_list(A) ::= . {
|
||||
A = array();
|
||||
}
|
||||
arg_list(A) ::= argument(X). {
|
||||
A = array(X);
|
||||
}
|
||||
arg_list(A) ::= arg_list(L) COMA argument(X). {
|
||||
array_push(L, X);
|
||||
A = L;
|
||||
}
|
||||
argument(A) ::= expression_prio4(X). { A = X; }
|
||||
argument(A) ::= INTERVAL expression_prio4(X) interval_unit(Y). { A = new IntervalOqlExpression(X, Y); }
|
||||
|
||||
interval_unit(A) ::= F_SECOND(X). { A = X; }
|
||||
interval_unit(A) ::= F_MINUTE(X). { A = X; }
|
||||
interval_unit(A) ::= F_HOUR(X). { A = X; }
|
||||
interval_unit(A) ::= F_DAY(X). { A = X; }
|
||||
interval_unit(A) ::= F_MONTH(X). { A = X; }
|
||||
interval_unit(A) ::= F_YEAR(X). { A = X; }
|
||||
|
||||
scalar(A) ::= num_scalar(X). { A = X; }
|
||||
scalar(A) ::= str_scalar(X). { A = X; }
|
||||
|
||||
num_scalar(A) ::= num_value(X). { A = new ScalarOqlExpression(X); }
|
||||
str_scalar(A) ::= str_value(X). { A = new ScalarOqlExpression(X); }
|
||||
|
||||
field_id(A) ::= name(X). { A = new FieldOqlExpression(X); }
|
||||
field_id(A) ::= class_name(X) DOT name(Y). { A = new FieldOqlExpression(Y, X); }
|
||||
class_name(A) ::= name(X). { A=X; }
|
||||
|
||||
|
||||
var_name(A) ::= VARNAME(X). { A = new VariableOqlExpression(substr(X, 1)); }
|
||||
|
||||
name(A) ::= NAME(X). {
|
||||
if (X[0] == '`')
|
||||
{
|
||||
$name = substr(X, 1, strlen(X) - 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
$name = X;
|
||||
}
|
||||
A = new OqlName($name, $this->m_iColPrev);
|
||||
}
|
||||
|
||||
num_value(A) ::= NUMVAL(X). {A=X;}
|
||||
str_value(A) ::= STRVAL(X). {A=stripslashes(substr(X, 1, strlen(X) - 2));}
|
||||
|
||||
|
||||
operator1(A) ::= num_operator1(X). {A=X;}
|
||||
operator2(A) ::= num_operator2(X). {A=X;}
|
||||
operator2(A) ::= str_operator(X). {A=X;}
|
||||
operator2(A) ::= EQ(X). {A=X;}
|
||||
operator2(A) ::= NOT_EQ(X). {A=X;}
|
||||
operator3(A) ::= LOG_AND(X). {A=X;}
|
||||
operator4(A) ::= LOG_OR(X). {A=X;}
|
||||
|
||||
num_operator1(A) ::= MATH_DIV(X). {A=X;}
|
||||
num_operator1(A) ::= MATH_MULT(X). {A=X;}
|
||||
num_operator2(A) ::= MATH_PLUS(X). {A=X;}
|
||||
num_operator2(A) ::= MATH_MINUS(X). {A=X;}
|
||||
num_operator2(A) ::= GT(X). {A=X;}
|
||||
num_operator2(A) ::= LT(X). {A=X;}
|
||||
num_operator2(A) ::= GE(X). {A=X;}
|
||||
num_operator2(A) ::= LE(X). {A=X;}
|
||||
|
||||
str_operator(A) ::= LIKE(X). {A=X;}
|
||||
str_operator(A) ::= NOT_LIKE(X). {A=X;}
|
||||
|
||||
list_operator(A) ::= IN(X). {A=X;}
|
||||
list_operator(A) ::= NOT_IN(X). {A=X;}
|
||||
|
||||
func_name(A) ::= F_IF(X). { A=X; }
|
||||
func_name(A) ::= F_ELT(X). { A=X; }
|
||||
func_name(A) ::= F_COALESCE(X). { A=X; }
|
||||
func_name(A) ::= F_CONCAT(X). { A=X; }
|
||||
func_name(A) ::= F_SUBSTR(X). { A=X; }
|
||||
func_name(A) ::= F_TRIM(X). { A=X; }
|
||||
func_name(A) ::= F_DATE(X). { A=X; }
|
||||
func_name(A) ::= F_DATE_FORMAT(X). { A=X; }
|
||||
func_name(A) ::= F_CURRENT_DATE(X). { A=X; }
|
||||
func_name(A) ::= F_NOW(X). { A=X; }
|
||||
func_name(A) ::= F_TIME(X). { A=X; }
|
||||
func_name(A) ::= F_TO_DAYS(X). { A=X; }
|
||||
func_name(A) ::= F_FROM_DAYS(X). { A=X; }
|
||||
func_name(A) ::= F_YEAR(X). { A=X; }
|
||||
func_name(A) ::= F_MONTH(X). { A=X; }
|
||||
func_name(A) ::= F_DAY(X). { A=X; }
|
||||
func_name(A) ::= F_DATE_ADD(X). { A=X; }
|
||||
func_name(A) ::= F_DATE_SUB(X). { A=X; }
|
||||
func_name(A) ::= F_ROUND(X). { A=X; }
|
||||
func_name(A) ::= F_FLOOR(X). { A=X; }
|
||||
func_name(A) ::= F_INET_ATON(X). { A=X; }
|
||||
func_name(A) ::= F_INET_NTOA(X). { A=X; }
|
||||
|
||||
|
||||
%code {
|
||||
|
||||
class OQLParserException extends OQLException
|
||||
{
|
||||
public function __construct($sInput, $iLine, $iCol, $sTokenName, $sTokenValue)
|
||||
{
|
||||
$sIssue = "Unexpected token $sTokenName";
|
||||
|
||||
parent::__construct($sIssue, $sInput, $iLine, $iCol, $sTokenValue);
|
||||
}
|
||||
}
|
||||
|
||||
class OQLParser extends OQLParserRaw
|
||||
{
|
||||
// dirty, but working for us (no other mean to get the final result :-(
|
||||
protected $my_result;
|
||||
|
||||
public function GetResult()
|
||||
{
|
||||
return $this->my_result;
|
||||
}
|
||||
|
||||
// More info on the source query and the current position while parsing it
|
||||
// Data used when an exception is raised
|
||||
protected $m_iLine; // still not used
|
||||
protected $m_iCol;
|
||||
protected $m_iColPrev; // this is the interesting one, because the parser will reduce on the next token
|
||||
protected $m_sSourceQuery;
|
||||
|
||||
public function __construct($sQuery)
|
||||
{
|
||||
$this->m_iLine = 0;
|
||||
$this->m_iCol = 0;
|
||||
$this->m_iColPrev = 0;
|
||||
$this->m_sSourceQuery = $sQuery;
|
||||
// no constructor - parent::__construct();
|
||||
}
|
||||
|
||||
public function doParse($token, $value, $iCurrPosition = 0)
|
||||
{
|
||||
$this->m_iColPrev = $this->m_iCol;
|
||||
$this->m_iCol = $iCurrPosition;
|
||||
|
||||
return parent::DoParse($token, $value);
|
||||
}
|
||||
|
||||
public function doFinish()
|
||||
{
|
||||
$this->doParse(0, 0);
|
||||
return $this->my_result;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
// Bug in the original destructor, causing an infinite loop !
|
||||
// This is a real issue when a fatal error occurs on the first token (the error could not be seen)
|
||||
if (is_null($this->yyidx))
|
||||
{
|
||||
$this->yyidx = -1;
|
||||
}
|
||||
parent::__destruct();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
78
core/oql/oqlexception.class.inc.php
Normal file
78
core/oql/oqlexception.class.inc.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
class OQLException extends CoreException
|
||||
{
|
||||
public function __construct($sIssue, $sInput, $iLine, $iCol, $sUnexpected, $aExpecting = null)
|
||||
{
|
||||
$this->m_MyIssue = $sIssue;
|
||||
$this->m_sInput = $sInput;
|
||||
$this->m_iLine = $iLine;
|
||||
$this->m_iCol = $iCol;
|
||||
$this->m_sUnexpected = $sUnexpected;
|
||||
$this->m_aExpecting = $aExpecting;
|
||||
|
||||
if (is_null($this->m_aExpecting) || (count($this->m_aExpecting) == 0))
|
||||
{
|
||||
$sMessage = "$sIssue - found '{$this->m_sUnexpected}' at $iCol in '$sInput'";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sExpectations = '{'.implode(', ', $this->m_aExpecting).'}';
|
||||
$sSuggest = self::FindClosestString($this->m_sUnexpected, $this->m_aExpecting);
|
||||
$sMessage = "$sIssue - found '{$this->m_sUnexpected}' at $iCol in '$sInput', expecting $sExpectations, I would suggest to use '$sSuggest'";
|
||||
}
|
||||
|
||||
// make sure everything is assigned properly
|
||||
parent::__construct($sMessage, 0);
|
||||
}
|
||||
|
||||
public function getHtmlDesc($sHighlightHtmlBegin = '<b>', $sHighlightHtmlEnd = '</b>')
|
||||
{
|
||||
$sRet = htmlentities($this->m_MyIssue.", found '".$this->m_sUnexpected."' in: ");
|
||||
$sRet .= htmlentities(substr($this->m_sInput, 0, $this->m_iCol));
|
||||
$sRet .= $sHighlightHtmlBegin.htmlentities(substr($this->m_sInput, $this->m_iCol, strlen($this->m_sUnexpected))).$sHighlightHtmlEnd;
|
||||
$sRet .= htmlentities(substr($this->m_sInput, $this->m_iCol + strlen($this->m_sUnexpected)));
|
||||
|
||||
if (!is_null($this->m_aExpecting) && (count($this->m_aExpecting) > 0))
|
||||
{
|
||||
$sExpectations = '{'.implode(', ', $this->m_aExpecting).'}';
|
||||
$sRet .= ", expecting ".htmlentities($sExpectations);
|
||||
$sSuggest = self::FindClosestString($this->m_sUnexpected, $this->m_aExpecting);
|
||||
if (strlen($sSuggest) > 0)
|
||||
{
|
||||
$sRet .= ", I would suggest to use '$sHighlightHtmlBegin".htmlentities($sSuggest)."$sHighlightHtmlEnd'";
|
||||
}
|
||||
}
|
||||
|
||||
return $sRet;
|
||||
}
|
||||
|
||||
static protected function FindClosestString($sInput, $aDictionary)
|
||||
{
|
||||
// no shortest distance found, yet
|
||||
$fShortest = -1;
|
||||
$sRet = '';
|
||||
|
||||
// loop through words to find the closest
|
||||
foreach ($aDictionary as $sSuggestion)
|
||||
{
|
||||
// calculate the distance between the input string and the suggested one
|
||||
$fDist = levenshtein($sInput, $sSuggestion);
|
||||
if ($fDist == 0)
|
||||
{
|
||||
// Exact match
|
||||
return $sSuggestion;
|
||||
}
|
||||
|
||||
if ($fShortest < 0 || ($fDist < 4 && $fDist <= $fShortest))
|
||||
{
|
||||
// set the closest match, and shortest distance
|
||||
$sRet = $sSuggestion;
|
||||
$fShortest = $fDist;
|
||||
}
|
||||
}
|
||||
return $sRet;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
71
core/oql/oqlinterpreter.class.inc.php
Normal file
71
core/oql/oqlinterpreter.class.inc.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
class OqlNormalizeException extends OQLException
|
||||
{
|
||||
public function __construct($sIssue, $sInput, OqlName $oName, $aExpecting = null)
|
||||
{
|
||||
parent::__construct($sIssue, $sInput, 0, $oName->GetPos(), $oName->GetValue(), $aExpecting);
|
||||
}
|
||||
}
|
||||
|
||||
class OqlInterpreterException extends OQLException
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
class OqlInterpreter
|
||||
{
|
||||
public $m_sQuery;
|
||||
|
||||
public function __construct($sQuery)
|
||||
{
|
||||
$this->m_sQuery = $sQuery;
|
||||
}
|
||||
|
||||
protected function Parse()
|
||||
{
|
||||
$oLexer = new OQLLexer($this->m_sQuery);
|
||||
$oParser = new OQLParser($this->m_sQuery);
|
||||
|
||||
while($oLexer->yylex())
|
||||
{
|
||||
$oParser->doParse($oLexer->token, $oLexer->value, $oLexer->getTokenPos());
|
||||
}
|
||||
$res = $oParser->doFinish();
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function ParseObjectQuery()
|
||||
{
|
||||
$oRes = $this->Parse();
|
||||
if (!$oRes instanceof OqlObjectQuery)
|
||||
{
|
||||
throw new OqlException('Expecting an OQL query', $this->m_sQuery, 0, 0, get_class($oRes), array('OqlObjectQuery'));
|
||||
}
|
||||
return $oRes;
|
||||
}
|
||||
|
||||
/*
|
||||
public function ParseValueSetQuery()
|
||||
{
|
||||
$oRes = $this->Parse();
|
||||
if (!$oRes instanceof OqlValueSetQuery)
|
||||
{
|
||||
throw new OqlException('Expecting a value set query', $this->m_sQuery, 0, 0, get_class($oRes), array('OqlValueSetQuery'));
|
||||
}
|
||||
return $oRes;
|
||||
}
|
||||
*/
|
||||
|
||||
public function ParseExpression()
|
||||
{
|
||||
$oRes = $this->Parse();
|
||||
if (!$oRes instanceof Expression)
|
||||
{
|
||||
throw new OqlException('Expecting an OQL expression', $this->m_sQuery, 0, 0, get_class($oRes), array('Expression'));
|
||||
}
|
||||
return $oRes;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
198
core/oql/oqlquery.class.inc.php
Normal file
198
core/oql/oqlquery.class.inc.php
Normal file
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
// Position a string within an OQL query
|
||||
// This is a must if we want to be able to pinpoint an error at any stage of the query interpretation
|
||||
// In particular, the normalization phase requires this
|
||||
class OqlName
|
||||
{
|
||||
protected $m_sValue;
|
||||
protected $m_iPos;
|
||||
|
||||
public function __construct($sValue, $iPos)
|
||||
{
|
||||
$this->m_iPos = $iPos;
|
||||
$this->m_sValue = $sValue;
|
||||
}
|
||||
|
||||
public function GetValue()
|
||||
{
|
||||
return $this->m_sValue;
|
||||
}
|
||||
|
||||
public function GetPos()
|
||||
{
|
||||
return $this->m_iPos;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->m_sValue;
|
||||
}
|
||||
}
|
||||
|
||||
class OqlJoinSpec
|
||||
{
|
||||
protected $m_oClass;
|
||||
protected $m_oClassAlias;
|
||||
protected $m_oLeftField;
|
||||
protected $m_oRightField;
|
||||
|
||||
protected $m_oNextJoinspec;
|
||||
|
||||
public function __construct($oClass, $oClassAlias, BinaryExpression $oExpression)
|
||||
{
|
||||
$this->m_oClass = $oClass;
|
||||
$this->m_oClassAlias = $oClassAlias;
|
||||
$this->m_oLeftField = $oExpression->GetLeftExpr();
|
||||
$this->m_oRightField = $oExpression->GetRightExpr();
|
||||
}
|
||||
|
||||
public function GetClass()
|
||||
{
|
||||
return $this->m_oClass->GetValue();
|
||||
}
|
||||
public function GetClassAlias()
|
||||
{
|
||||
return $this->m_oClassAlias->GetValue();
|
||||
}
|
||||
|
||||
public function GetClassDetails()
|
||||
{
|
||||
return $this->m_oClass;
|
||||
}
|
||||
public function GetClassAliasDetails()
|
||||
{
|
||||
return $this->m_oClassAlias;
|
||||
}
|
||||
|
||||
public function GetLeftField()
|
||||
{
|
||||
return $this->m_oLeftField;
|
||||
}
|
||||
public function GetRightField()
|
||||
{
|
||||
return $this->m_oRightField;
|
||||
}
|
||||
}
|
||||
|
||||
class BinaryOqlExpression extends BinaryExpression
|
||||
{
|
||||
}
|
||||
|
||||
class ScalarOqlExpression extends ScalarExpression
|
||||
{
|
||||
}
|
||||
|
||||
class FieldOqlExpression extends FieldExpression
|
||||
{
|
||||
protected $m_oParent;
|
||||
protected $m_oName;
|
||||
|
||||
public function __construct($oName, $oParent = null)
|
||||
{
|
||||
if (is_null($oParent))
|
||||
{
|
||||
$oParent = new OqlName('', 0);
|
||||
}
|
||||
$this->m_oParent = $oParent;
|
||||
$this->m_oName = $oName;
|
||||
|
||||
parent::__construct($oName->GetValue(), $oParent->GetValue());
|
||||
}
|
||||
|
||||
public function GetParentDetails()
|
||||
{
|
||||
return $this->m_oParent;
|
||||
}
|
||||
|
||||
public function GetNameDetails()
|
||||
{
|
||||
return $this->m_oName;
|
||||
}
|
||||
}
|
||||
|
||||
class VariableOqlExpression extends VariableExpression
|
||||
{
|
||||
}
|
||||
|
||||
class ListOqlExpression extends ListExpression
|
||||
{
|
||||
}
|
||||
|
||||
class FunctionOqlExpression extends FunctionExpression
|
||||
{
|
||||
}
|
||||
|
||||
class IntervalOqlExpression extends IntervalExpression
|
||||
{
|
||||
}
|
||||
|
||||
abstract class OqlQuery
|
||||
{
|
||||
protected $m_aJoins; // array of OqlJoinSpec
|
||||
protected $m_oCondition; // condition tree (expressions)
|
||||
|
||||
public function __construct($oCondition = null, $aJoins = null)
|
||||
{
|
||||
$this->m_aJoins = $aJoins;
|
||||
$this->m_oCondition = $oCondition;
|
||||
}
|
||||
|
||||
public function GetJoins()
|
||||
{
|
||||
return $this->m_aJoins;
|
||||
}
|
||||
public function GetCondition()
|
||||
{
|
||||
return $this->m_oCondition;
|
||||
}
|
||||
}
|
||||
|
||||
class OqlObjectQuery extends OqlQuery
|
||||
{
|
||||
protected $m_oClass;
|
||||
protected $m_oClassAlias;
|
||||
|
||||
public function __construct($oClass, $oClassAlias = '', $oCondition = null, $aJoins = null)
|
||||
{
|
||||
$this->m_oClass = $oClass;
|
||||
$this->m_oClassAlias = $oClassAlias;
|
||||
parent::__construct($oCondition, $aJoins);
|
||||
}
|
||||
|
||||
public function GetClass()
|
||||
{
|
||||
return $this->m_oClass->GetValue();
|
||||
}
|
||||
public function GetClassAlias()
|
||||
{
|
||||
return $this->m_oClassAlias->GetValue();
|
||||
}
|
||||
|
||||
public function GetClassDetails()
|
||||
{
|
||||
return $this->m_oClass;
|
||||
}
|
||||
public function GetClassAliasDetails()
|
||||
{
|
||||
return $this->m_oClassAlias;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class OqlValueSetQuery extends OqlObjectQuery
|
||||
{
|
||||
protected $m_oSelectExpr;
|
||||
|
||||
public function __construct($oSelectExpr, $oClass, $oClassAlias = '', $oCondition = null, $aJoins = null)
|
||||
{
|
||||
$this->m_oSelectExpr = $oSelectExpr;
|
||||
parent::__construct($oClass, $oClassAlias, $oCondition, $aJoins);
|
||||
}
|
||||
|
||||
public function GetSelectExpression()
|
||||
{
|
||||
return $this->m_oSelectExpr;
|
||||
}
|
||||
}
|
||||
?>
|
||||
135
core/ormdocument.class.inc.php
Normal file
135
core/ormdocument.class.inc.php
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ormDocument
|
||||
* encapsulate the behavior of a binary data set that will be stored an attribute of class AttributeBlob
|
||||
*
|
||||
* @package tbd
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
*/
|
||||
|
||||
class ormDocument
|
||||
{
|
||||
protected $m_data;
|
||||
protected $m_sMimeType;
|
||||
protected $m_sFileName;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($data = null, $sMimeType = 'text/plain', $sFileName = '')
|
||||
{
|
||||
$this->m_data = $data;
|
||||
$this->m_sMimeType = $sMimeType;
|
||||
$this->m_sFileName = $sFileName;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return MyHelpers::beautifulstr($this->m_data, 100, true);
|
||||
}
|
||||
|
||||
public function IsEmpty()
|
||||
{
|
||||
return ($this->m_data == null);
|
||||
}
|
||||
|
||||
public function GetMimeType()
|
||||
{
|
||||
return $this->m_sMimeType;
|
||||
}
|
||||
public function GetMainMimeType()
|
||||
{
|
||||
$iSeparatorPos = strpos($this->m_sMimeType, '/');
|
||||
if ($iSeparatorPos > 0)
|
||||
{
|
||||
return substr($this->m_sMimeType, 0, $iSeparatorPos);
|
||||
}
|
||||
return $this->m_sMimeType;
|
||||
}
|
||||
|
||||
public function GetData()
|
||||
{
|
||||
return $this->m_data;
|
||||
}
|
||||
|
||||
public function GetFileName()
|
||||
{
|
||||
return $this->m_sFileName;
|
||||
}
|
||||
|
||||
public function GetAsHTML()
|
||||
{
|
||||
$sResult = '';
|
||||
if ($this->IsEmpty())
|
||||
{
|
||||
// If the filename is not empty, display it, this is used
|
||||
// by the creation wizard while the file has not yet been uploaded
|
||||
$sResult = $this->GetFileName();
|
||||
}
|
||||
else
|
||||
{
|
||||
$data = $this->GetData();
|
||||
$sResult = $this->GetFileName().' [ '.$this->GetMimeType().', size: '.strlen($data).' byte(s) ]';
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an HTML fragment that will display the document *inline* (if possible)
|
||||
* @return string
|
||||
*/
|
||||
public function GetDisplayInline($sClass, $Id, $sAttCode)
|
||||
{
|
||||
switch ($this->GetMainMimeType())
|
||||
{
|
||||
case 'text':
|
||||
case 'html':
|
||||
$data = $this->GetData();
|
||||
switch($this->GetMimeType())
|
||||
{
|
||||
case 'text/html':
|
||||
case 'text/xml':
|
||||
return "<iframe src=\"../pages/ajax.render.php?operation=display_document&class=$sClass&id=$Id&field=$sAttCode\" width=\"100%\" height=\"400\">Loading...</iframe>\n";
|
||||
|
||||
default:
|
||||
return "<pre>".htmlentities(MyHelpers::beautifulstr($data, 1000, true))."</pre>\n";
|
||||
}
|
||||
break; // Not really needed, but...
|
||||
|
||||
case 'application':
|
||||
switch($this->GetMimeType())
|
||||
{
|
||||
case 'application/pdf':
|
||||
return "<iframe src=\"../pages/ajax.render.php?operation=display_document&class=$sClass&id=$Id&field=$sAttCode\" width=\"100%\" height=\"400\">Loading...</iframe>\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'image':
|
||||
return "<img src=\"../pages/ajax.render.php?operation=display_document&class=$sClass&id=$Id&field=$sAttCode\" />\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an hyperlink to display the document *inline*
|
||||
* @return string
|
||||
*/
|
||||
public function GetDisplayLink($sClass, $Id, $sAttCode)
|
||||
{
|
||||
return "<a href=\"../pages/ajax.render.php?operation=display_document&class=$sClass&id=$Id&field=$sAttCode\" target=\"_blank\" >".$this->GetFileName()."</a>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an hyperlink to download the document (content-disposition: attachment)
|
||||
* @return string
|
||||
*/
|
||||
public function GetDownloadLink($sClass, $Id, $sAttCode)
|
||||
{
|
||||
return "<a href=\"../pages/ajax.render.php?operation=download_document&class=$sClass&id=$Id&field=$sAttCode\">".$this->GetFileName()."</a>\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
416
core/sqlquery.class.inc.php
Normal file
416
core/sqlquery.class.inc.php
Normal file
@@ -0,0 +1,416 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* SQLQuery
|
||||
* build an mySQL compatible SQL query
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
require_once('cmdbsource.class.inc.php');
|
||||
|
||||
|
||||
class SQLExpression extends BinaryExpression
|
||||
{
|
||||
}
|
||||
class ScalarSQLExpression extends ScalarExpression
|
||||
{
|
||||
}
|
||||
class TrueSQLExpression extends TrueExpression
|
||||
{
|
||||
}
|
||||
class FieldSQLExpression extends FieldExpression
|
||||
{
|
||||
}
|
||||
class VariableSQLExpression extends VariableExpression
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
class SQLQuery
|
||||
{
|
||||
private $m_sTable = '';
|
||||
private $m_sTableAlias = '';
|
||||
private $m_aFields = array();
|
||||
private $m_oConditionExpr = null;
|
||||
private $m_aFullTextNeedles = array();
|
||||
private $m_bToDelete = true; // The current table must be listed for deletion ?
|
||||
private $m_aValues = array(); // Values to set in case of an update query
|
||||
private $m_aJoinSelects = array();
|
||||
|
||||
public function __construct($sTable, $sTableAlias, $aFields, $oConditionExpr, $aFullTextNeedles, $bToDelete = true, $aValues = array())
|
||||
{
|
||||
if (!CMDBSource::IsTable($sTable))
|
||||
{
|
||||
throw new CoreException("Unknown table '$sTable'");
|
||||
}
|
||||
// $aFields must be an array of "alias"=>"expr"
|
||||
// $oConditionExpr must be a condition tree
|
||||
// $aValues is an array of "alias"=>value
|
||||
|
||||
$this->m_sTable = $sTable;
|
||||
$this->m_sTableAlias = $sTableAlias;
|
||||
$this->m_aFields = $aFields;
|
||||
$this->m_oConditionExpr = $oConditionExpr;
|
||||
if (is_null($oConditionExpr))
|
||||
{
|
||||
$this->m_oConditionExpr = new TrueExpression;
|
||||
}
|
||||
else if (!$oConditionExpr instanceof Expression)
|
||||
{
|
||||
throw new CoreException('Invalid type for condition, expecting an Expression', array('class' => get_class($oConditionExpr)));
|
||||
}
|
||||
$this->m_aFullTextNeedles = $aFullTextNeedles;
|
||||
$this->m_bToDelete = $bToDelete;
|
||||
$this->m_aValues = $aValues;
|
||||
}
|
||||
|
||||
public function DisplayHtml()
|
||||
{
|
||||
if (count($this->m_aFields) == 0) $sFields = "";
|
||||
else
|
||||
{
|
||||
$aFieldDesc = array();
|
||||
foreach ($this->m_aFields as $sAlias => $oExpression)
|
||||
{
|
||||
$aFieldDesc[] = $oExpression->Render()." as <em>$sAlias</em>";
|
||||
}
|
||||
$sFields = " => ".implode(', ', $aFieldDesc);
|
||||
}
|
||||
echo "<b>$this->m_sTable</b>$sFields<br/>\n";
|
||||
// #@# todo - display html of an expression tree
|
||||
//$this->m_oConditionExpr->DisplayHtml()
|
||||
if (count($this->m_aFullTextNeedles) > 0)
|
||||
{
|
||||
echo "Full text criteria...<br/>\n";
|
||||
echo "<ul class=\"treeview\">\n";
|
||||
foreach ($this->m_aFullTextNeedles as $sFTNeedle)
|
||||
{
|
||||
echo "<li>$sFTNeedle</li>\n";
|
||||
}
|
||||
echo "</ul>";
|
||||
}
|
||||
if (count($this->m_aJoinSelects) > 0)
|
||||
{
|
||||
echo "Joined to...<br/>\n";
|
||||
echo "<ul class=\"treeview\">\n";
|
||||
foreach ($this->m_aJoinSelects as $aJoinInfo)
|
||||
{
|
||||
$sJoinType = $aJoinInfo["jointype"];
|
||||
$oSQLQuery = $aJoinInfo["select"];
|
||||
$sLeftField = $aJoinInfo["leftfield"];
|
||||
$sRightField = $aJoinInfo["rightfield"];
|
||||
$sRightTableAlias = $aJoinInfo["righttablealias"];
|
||||
|
||||
echo "<li>Join '$sJoinType', $sLeftField, $sRightTableAlias.$sRightField".$oSQLQuery->DisplayHtml()."</li>\n";
|
||||
}
|
||||
echo "</ul>";
|
||||
}
|
||||
$aFrom = array();
|
||||
$aFields = array();
|
||||
$oCondition = null;
|
||||
$aDelTables = array();
|
||||
$aSetValues = array();
|
||||
$this->privRender($aFrom, $aFields, $oCondition, $aDelTables, $aSetValues);
|
||||
echo "From ...<br/>\n";
|
||||
echo "<pre style=\"font-size: smaller;\">\n";
|
||||
print_r($aFrom);
|
||||
echo "</pre>";
|
||||
}
|
||||
|
||||
public function SetCondition($oConditionExpr)
|
||||
{
|
||||
$this->m_oConditionExpr = $oConditionExpr;
|
||||
}
|
||||
|
||||
public function AddCondition($oConditionExpr)
|
||||
{
|
||||
$this->m_oConditionExpr->LogAnd($oConditionExpr);
|
||||
}
|
||||
|
||||
private function AddJoin($sJoinType, $oSQLQuery, $sLeftField, $sRightField, $sRightTableAlias = '')
|
||||
{
|
||||
assert((get_class($oSQLQuery) == __CLASS__) || is_subclass_of($oSQLQuery, __CLASS__));
|
||||
if (!CMDBSource::IsField($this->m_sTable, $sLeftField))
|
||||
{
|
||||
throw new CoreException("Unknown field '$sLeftField' in table '".$this->m_sTable);
|
||||
}
|
||||
if (empty($sRightTableAlias))
|
||||
{
|
||||
$sRightTableAlias = $oSQLQuery->m_sTableAlias;
|
||||
}
|
||||
// #@# Could not be verified here because the namespace is unknown - do we need to check it there?
|
||||
//
|
||||
// if (!CMDBSource::IsField($sRightTable, $sRightField))
|
||||
// {
|
||||
// throw new CoreException("Unknown field '$sRightField' in table '".$sRightTable."'");
|
||||
// }
|
||||
|
||||
$this->m_aJoinSelects[] = array(
|
||||
"jointype" => $sJoinType,
|
||||
"select" => $oSQLQuery,
|
||||
"leftfield" => $sLeftField,
|
||||
"rightfield" => $sRightField,
|
||||
"righttablealias" => $sRightTableAlias
|
||||
);
|
||||
}
|
||||
public function AddInnerJoin($oSQLQuery, $sLeftField, $sRightField, $sRigthtTable = '')
|
||||
{
|
||||
$this->AddJoin("inner", $oSQLQuery, $sLeftField, $sRightField, $sRigthtTable);
|
||||
}
|
||||
public function AddLeftJoin($oSQLQuery, $sLeftField, $sRightField)
|
||||
{
|
||||
return $this->AddJoin("left", $oSQLQuery, $sLeftField, $sRightField);
|
||||
}
|
||||
|
||||
// Interface, build the SQL query
|
||||
public function RenderDelete($aArgs = array())
|
||||
{
|
||||
// The goal will be to complete the list as we build the Joins
|
||||
$aFrom = array();
|
||||
$aFields = array();
|
||||
$oCondition = null;
|
||||
$aDelTables = array();
|
||||
$aSetValues = array();
|
||||
$this->privRender($aFrom, $aFields, $oCondition, $aDelTables, $aSetValues);
|
||||
|
||||
// Target: DELETE myAlias1, myAlias2 FROM t1 as myAlias1, t2 as myAlias2, t3 as topreserve WHERE ...
|
||||
|
||||
$sDelete = self::ClauseDelete($aDelTables);
|
||||
$sFrom = self::ClauseFrom($aFrom);
|
||||
// #@# safety net to redo ?
|
||||
/*
|
||||
if ($this->m_oConditionExpr->IsAny())
|
||||
-- if (count($aConditions) == 0) --
|
||||
{
|
||||
throw new CoreException("Building a request wich will delete every object of a given table -looks suspicious- please use truncate instead...");
|
||||
}
|
||||
*/
|
||||
$sWhere = self::ClauseWhere($oCondition, $aArgs);
|
||||
return "DELETE $sDelete FROM $sFrom WHERE $sWhere";
|
||||
}
|
||||
|
||||
// Interface, build the SQL query
|
||||
public function RenderUpdate($aArgs = array())
|
||||
{
|
||||
// The goal will be to complete the list as we build the Joins
|
||||
$aFrom = array();
|
||||
$aFields = array();
|
||||
$oCondition = null;
|
||||
$aDelTables = array();
|
||||
$aSetValues = array();
|
||||
$this->privRender($aFrom, $aFields, $oCondition, $aDelTables, $aSetValues);
|
||||
|
||||
$sFrom = self::ClauseFrom($aFrom);
|
||||
$sValues = self::ClauseValues($aSetValues);
|
||||
$sWhere = self::ClauseWhere($oCondition, $aArgs);
|
||||
return "UPDATE $sFrom SET $sValues WHERE $sWhere";
|
||||
}
|
||||
|
||||
// Interface, build the SQL query
|
||||
public function RenderSelect($aOrderBy = array(), $aArgs = array())
|
||||
{
|
||||
// The goal will be to complete the lists as we build the Joins
|
||||
$aFrom = array();
|
||||
$aFields = array();
|
||||
$oCondition = null;
|
||||
$aDelTables = array();
|
||||
$aSetValues = array();
|
||||
$this->privRender($aFrom, $aFields, $oCondition, $aDelTables, $aSetValues);
|
||||
|
||||
$sSelect = self::ClauseSelect($aFields);
|
||||
$sFrom = self::ClauseFrom($aFrom);
|
||||
$sWhere = self::ClauseWhere($oCondition, $aArgs);
|
||||
$sOrderBy = self::ClauseOrderBy($aOrderBy);
|
||||
if (!empty($sOrderBy))
|
||||
{
|
||||
$sOrderBy = "ORDER BY $sOrderBy";
|
||||
}
|
||||
return "SELECT DISTINCT $sSelect FROM $sFrom WHERE $sWhere $sOrderBy";
|
||||
}
|
||||
|
||||
private static function ClauseSelect($aFields)
|
||||
{
|
||||
$aSelect = array();
|
||||
foreach ($aFields as $sFieldAlias => $sSQLExpr)
|
||||
{
|
||||
$aSelect[] = "$sSQLExpr AS $sFieldAlias";
|
||||
}
|
||||
$sSelect = implode(', ', $aSelect);
|
||||
return $sSelect;
|
||||
}
|
||||
|
||||
private static function ClauseDelete($aDelTableAliases)
|
||||
{
|
||||
$aDelTables = array();
|
||||
foreach ($aDelTableAliases as $sTableAlias)
|
||||
{
|
||||
$aDelTables[] = "$sTableAlias";
|
||||
}
|
||||
$sDelTables = implode(', ', $aDelTables);
|
||||
return $sDelTables;
|
||||
}
|
||||
|
||||
private static function ClauseFrom($aFrom)
|
||||
{
|
||||
$sFrom = "";
|
||||
foreach ($aFrom as $sTableAlias => $aJoinInfo)
|
||||
{
|
||||
switch ($aJoinInfo["jointype"])
|
||||
{
|
||||
case "first":
|
||||
$sFrom .= "`".$aJoinInfo["tablename"]."` AS `$sTableAlias`";
|
||||
$sFrom .= " ".self::ClauseFrom($aJoinInfo["subfrom"]);
|
||||
break;
|
||||
case "inner":
|
||||
$sFrom .= " INNER JOIN (`".$aJoinInfo["tablename"]."` AS `$sTableAlias`";
|
||||
$sFrom .= " ".self::ClauseFrom($aJoinInfo["subfrom"]);
|
||||
$sFrom .= ") ON ".$aJoinInfo["joincondition"];
|
||||
break;
|
||||
case "left":
|
||||
$sFrom .= " LEFT JOIN (`".$aJoinInfo["tablename"]."` AS `$sTableAlias`";
|
||||
$sFrom .= " ".self::ClauseFrom($aJoinInfo["subfrom"]);
|
||||
$sFrom .= ") ON ".$aJoinInfo["joincondition"];
|
||||
break;
|
||||
default:
|
||||
throw new CoreException("Unknown jointype: '".$aJoinInfo["jointype"]."'");
|
||||
}
|
||||
}
|
||||
return $sFrom;
|
||||
}
|
||||
|
||||
private static function ClauseValues($aValues)
|
||||
{
|
||||
$aSetValues = array();
|
||||
foreach ($aValues as $sFieldSpec => $value)
|
||||
{
|
||||
$aSetValues[] = "$sFieldSpec = ".CMDBSource::Quote($value);
|
||||
}
|
||||
$sSetValues = implode(', ', $aSetValues);
|
||||
return $sSetValues;
|
||||
}
|
||||
|
||||
private static function ClauseWhere($oConditionExpr, $aArgs = array())
|
||||
{
|
||||
return $oConditionExpr->Render($aArgs);
|
||||
}
|
||||
|
||||
private static function ClauseOrderBy($aOrderBy)
|
||||
{
|
||||
$aOrderBySpec = array();
|
||||
foreach($aOrderBy as $sFieldAlias => $bAscending)
|
||||
{
|
||||
$aOrderBySpec[] = '`'.$sFieldAlias.'`'.($bAscending ? " ASC" : " DESC");
|
||||
}
|
||||
$sOrderBy = implode(", ", $aOrderBySpec);
|
||||
return $sOrderBy;
|
||||
}
|
||||
|
||||
// Purpose: prepare the query data, once for all
|
||||
private function privRender(&$aFrom, &$aFields, &$oCondition, &$aDelTables, &$aSetValues)
|
||||
{
|
||||
$sTableAlias = $this->privRenderSingleTable($aFrom, $aFields, $aDelTables, $aSetValues);
|
||||
|
||||
// Add the full text search condition, based on each and every requested field
|
||||
//
|
||||
// To be updated with a real full text search based on the mySQL settings
|
||||
// (then it might move somewhere else !)
|
||||
//
|
||||
$oCondition = $this->m_oConditionExpr;
|
||||
if ((count($aFields) > 0) && (count($this->m_aFullTextNeedles) > 0))
|
||||
{
|
||||
$aFieldExp = array();
|
||||
foreach ($aFields as $sField)
|
||||
{
|
||||
// This is TEMPORARY (that's why it is weird, actually)
|
||||
// Full text match will be done as an expression in the filter condition
|
||||
|
||||
// $sField is already a string `table`.`column`
|
||||
// Let's make an expression out of it (again !)
|
||||
$aFieldExp[] = Expression::FromOQL($sField);
|
||||
}
|
||||
$oFullTextExpr = new CharConcatExpression($aFieldExp);
|
||||
// The cast is necessary because the CONCAT result in a binary string:
|
||||
// if any of the field is a binary string => case sensitive comparison
|
||||
//
|
||||
foreach($this->m_aFullTextNeedles as $sFTNeedle)
|
||||
{
|
||||
$oNewCond = new BinaryExpression($oFullTextExpr, 'LIKE', new ScalarExpression("%$sFTNeedle%"));
|
||||
$oCondition = $oCondition->LogAnd($oNewCond);
|
||||
}
|
||||
}
|
||||
|
||||
return $sTableAlias;
|
||||
}
|
||||
|
||||
private function privRenderSingleTable(&$aFrom, &$aFields, &$aDelTables, &$aSetValues, $sJoinType = 'first', $sCallerAlias = '', $sLeftField = '', $sRightField = '', $sRightTableAlias = '')
|
||||
{
|
||||
$aActualTableFields = CMDBSource::GetTableFieldsList($this->m_sTable);
|
||||
|
||||
$aTranslationTable[$this->m_sTable]['*'] = $this->m_sTableAlias;
|
||||
|
||||
// Handle the various kinds of join (or first table in the list)
|
||||
//
|
||||
if (empty($sRightTableAlias))
|
||||
{
|
||||
$sRightTableAlias = $this->m_sTableAlias;
|
||||
}
|
||||
$sJoinCond = "`$sCallerAlias`.`$sLeftField` = `$sRightTableAlias`.`$sRightField`";
|
||||
switch ($sJoinType)
|
||||
{
|
||||
case "first":
|
||||
$aFrom[$this->m_sTableAlias] = array("jointype"=>"first", "tablename"=>$this->m_sTable, "joincondition"=>"");
|
||||
break;
|
||||
case "inner":
|
||||
case "left":
|
||||
// table or tablealias ???
|
||||
$aFrom[$this->m_sTableAlias] = array("jointype"=>$sJoinType, "tablename"=>$this->m_sTable, "joincondition"=>"$sJoinCond");
|
||||
break;
|
||||
}
|
||||
|
||||
// Given the alias, modify the fields and conditions
|
||||
// before adding them into the current lists
|
||||
//
|
||||
foreach($this->m_aFields as $sAlias => $oExpression)
|
||||
{
|
||||
$sTable = $oExpression->GetParent();
|
||||
$sColumn = $oExpression->GetName();
|
||||
$aFields["`$sAlias`"] = $oExpression->Render();
|
||||
}
|
||||
if ($this->m_bToDelete)
|
||||
{
|
||||
$aDelTables[] = "`{$this->m_sTableAlias}`";
|
||||
}
|
||||
foreach($this->m_aValues as $sFieldName=>$value)
|
||||
{
|
||||
$aSetValues["`{$this->m_sTableAlias}`.`$sFieldName`"] = $value; // quoted further!
|
||||
}
|
||||
|
||||
// loop on joins, to complete the list of tables/fields/conditions
|
||||
//
|
||||
$aTempFrom = array(); // temporary subset of 'from' specs, to be grouped in the final query
|
||||
foreach ($this->m_aJoinSelects as $aJoinData)
|
||||
{
|
||||
$sJoinType = $aJoinData["jointype"];
|
||||
$oRightSelect = $aJoinData["select"];
|
||||
$sLeftField = $aJoinData["leftfield"];
|
||||
$sRightField = $aJoinData["rightfield"];
|
||||
$sRightTableAlias = $aJoinData["righttablealias"];
|
||||
|
||||
$sJoinTableAlias = $oRightSelect->privRenderSingleTable($aTempFrom, $aFields, $aDelTables, $aSetValues, $sJoinType, $this->m_sTableAlias, $sLeftField, $sRightField, $sRightTableAlias);
|
||||
}
|
||||
$aFrom[$this->m_sTableAlias]['subfrom'] = $aTempFrom;
|
||||
|
||||
return $this->m_sTableAlias;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
59
core/stimulus.class.inc.php
Normal file
59
core/stimulus.class.inc.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* A stimulus is the trigger that makes the lifecycle go ahead (state machine)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
class ObjectStimulus
|
||||
{
|
||||
private $m_aParams = array();
|
||||
|
||||
public function __construct($aParams)
|
||||
{
|
||||
$this->m_aParams = $aParams;
|
||||
$this->ConsistencyCheck();
|
||||
}
|
||||
|
||||
public function Get($sParamName) {return $this->m_aParams[$sParamName];}
|
||||
|
||||
// Note: I could factorize this code with the parameter management made for the AttributeDef class
|
||||
// to be overloaded
|
||||
static protected function ListExpectedParams()
|
||||
{
|
||||
return array("label", "description");
|
||||
}
|
||||
|
||||
private function ConsistencyCheck()
|
||||
{
|
||||
|
||||
// Check that any mandatory param has been specified
|
||||
//
|
||||
$aExpectedParams = $this->ListExpectedParams();
|
||||
foreach($aExpectedParams as $sParamName)
|
||||
{
|
||||
if (!array_key_exists($sParamName, $this->m_aParams))
|
||||
{
|
||||
$aBacktrace = debug_backtrace();
|
||||
$sTargetClass = $aBacktrace[2]["class"];
|
||||
$sCodeInfo = $aBacktrace[1]["file"]." - ".$aBacktrace[1]["line"];
|
||||
throw new CoreException("missing parameter '$sParamName' in ".get_class($this)." declaration for class $sTargetClass ($sCodeInfo)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class StimulusUserAction extends ObjectStimulus
|
||||
{
|
||||
}
|
||||
|
||||
?>
|
||||
567
core/test.class.inc.php
Normal file
567
core/test.class.inc.php
Normal file
@@ -0,0 +1,567 @@
|
||||
<?php
|
||||
|
||||
require_once('coreexception.class.inc.php');
|
||||
require_once('attributedef.class.inc.php');
|
||||
require_once('filterdef.class.inc.php');
|
||||
require_once('stimulus.class.inc.php');
|
||||
require_once('MyHelpers.class.inc.php');
|
||||
|
||||
require_once('expression.class.inc.php');
|
||||
require_once('cmdbsource.class.inc.php');
|
||||
require_once('sqlquery.class.inc.php');
|
||||
|
||||
require_once('dbobject.class.php');
|
||||
require_once('dbobjectsearch.class.php');
|
||||
require_once('dbobjectset.class.php');
|
||||
|
||||
require_once('userrights.class.inc.php');
|
||||
|
||||
require_once('../webservices/webservices.class.inc.php');
|
||||
|
||||
|
||||
// Just to differentiate programmatically triggered exceptions and other kind of errors (usefull?)
|
||||
class UnitTestException extends Exception
|
||||
{}
|
||||
|
||||
|
||||
/**
|
||||
* Improved display of the backtrace
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class ExceptionFromError extends Exception
|
||||
{
|
||||
public function getTraceAsHtml()
|
||||
{
|
||||
$aBackTrace = $this->getTrace();
|
||||
return MyHelpers::get_callstack_html(0, $this->getTrace());
|
||||
// return "<pre>\n".$this->getTraceAsString()."</pre>\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test handler API and basic helpers
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
abstract class TestHandler
|
||||
{
|
||||
protected $m_aSuccesses;
|
||||
protected $m_aWarnings;
|
||||
protected $m_aErrors;
|
||||
protected $m_sOutput;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->m_aSuccesses = array();
|
||||
$this->m_aWarnings = array();
|
||||
$this->m_aErrors = array();
|
||||
}
|
||||
|
||||
abstract static public function GetName();
|
||||
abstract static public function GetDescription();
|
||||
|
||||
protected function DoPrepare() {return true;}
|
||||
abstract protected function DoExecute();
|
||||
protected function DoCleanup() {return true;}
|
||||
|
||||
protected function ReportSuccess($sMessage, $sSubtestId = '')
|
||||
{
|
||||
$this->m_aSuccesses[] = $sMessage;
|
||||
}
|
||||
|
||||
protected function ReportWarning($sMessage, $sSubtestId = '')
|
||||
{
|
||||
$this->m_aWarnings[] = $sMessage;
|
||||
}
|
||||
|
||||
protected function ReportError($sMessage, $sSubtestId = '')
|
||||
{
|
||||
$this->m_aErrors[] = $sMessage;
|
||||
}
|
||||
|
||||
public function GetResults()
|
||||
{
|
||||
return $this->m_aSuccesses;
|
||||
}
|
||||
|
||||
public function GetWarnings()
|
||||
{
|
||||
return $this->m_aWarnings;
|
||||
}
|
||||
|
||||
public function GetErrors()
|
||||
{
|
||||
return $this->m_aErrors;
|
||||
}
|
||||
|
||||
public function GetOutput()
|
||||
{
|
||||
return $this->m_sOutput;
|
||||
}
|
||||
|
||||
public function error_handler($errno, $errstr, $errfile, $errline)
|
||||
{
|
||||
// Note: return false to call the default handler (stop the program if an error)
|
||||
|
||||
switch ($errno)
|
||||
{
|
||||
case E_USER_ERROR:
|
||||
$this->ReportError($errstr);
|
||||
//throw new ExceptionFromError("Fatal error in line $errline of file $errfile: $errstr");
|
||||
break;
|
||||
case E_USER_WARNING:
|
||||
$this->ReportWarning($errstr);
|
||||
break;
|
||||
case E_USER_NOTICE:
|
||||
$this->ReportWarning($errstr);
|
||||
break;
|
||||
default:
|
||||
$this->ReportWarning("Unknown error type: [$errno] $errstr in $errfile at $errline");
|
||||
echo "Unknown error type: [$errno] $errstr in $errfile at $errline<br />\n";
|
||||
break;
|
||||
}
|
||||
return true; // do not call the default handler
|
||||
}
|
||||
|
||||
public function Execute()
|
||||
{
|
||||
ob_start();
|
||||
set_error_handler(array($this, 'error_handler'));
|
||||
try
|
||||
{
|
||||
$this->DoPrepare();
|
||||
$this->DoExecute();
|
||||
}
|
||||
catch (ExceptionFromError $e)
|
||||
{
|
||||
$this->ReportError($e->getMessage().' - '.$e->getTraceAsHtml());
|
||||
}
|
||||
catch (CoreException $e)
|
||||
{
|
||||
//$this->ReportError($e->getMessage());
|
||||
//$this->ReportError($e->__tostring());
|
||||
$this->ReportError($e->getMessage().' - '.$e->getTraceAsHtml());
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
//$this->ReportError($e->getMessage());
|
||||
//$this->ReportError($e->__tostring());
|
||||
$this->ReportError('class '.get_class($e).' --- '.$e->getMessage().' - '.$e->getTraceAsString());
|
||||
}
|
||||
restore_error_handler();
|
||||
$this->m_sOutput = ob_get_clean();
|
||||
return (count($this->GetErrors()) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test to execute a piece of code (checks if an error occurs)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
abstract class TestFunction extends TestHandler
|
||||
{
|
||||
// simply overload DoExecute (temporary)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test to execute a piece of code (checks if an error occurs)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
abstract class TestWebServices extends TestHandler
|
||||
{
|
||||
// simply overload DoExecute (temporary)
|
||||
|
||||
static protected function DoPostRequestAuth($sRelativeUrl, $aData, $sLogin = 'admin', $sPassword = 'admin', $sOptionnalHeaders = null)
|
||||
{
|
||||
$aDataAndAuth = $aData;
|
||||
$aDataAndAuth['operation'] = 'login';
|
||||
$aDataAndAuth['auth_user'] = $sLogin;
|
||||
$aDataAndAuth['auth_pwd'] = $sPassword;
|
||||
$sHost = $_SERVER['HTTP_HOST'];
|
||||
$sRawPath = $_SERVER['SCRIPT_NAME'];
|
||||
$sPath = dirname($sRawPath);
|
||||
$sUrl = "http://$sHost/$sPath/$sRelativeUrl";
|
||||
|
||||
return self::DoPostRequest($sUrl, $aDataAndAuth, $sOptionnalHeaders);
|
||||
}
|
||||
|
||||
// Source: http://netevil.org/blog/2006/nov/http-post-from-php-without-curl
|
||||
// originaly named after do_post_request
|
||||
// Partially adapted to our coding conventions
|
||||
static protected function DoPostRequest($sUrl, $aData, $sOptionnalHeaders = null)
|
||||
{
|
||||
// $sOptionnalHeaders is a string containing additional HTTP headers that you would like to send in your request.
|
||||
|
||||
$sData = http_build_query($aData);
|
||||
|
||||
$aParams = array('http' => array(
|
||||
'method' => 'POST',
|
||||
'content' => $sData,
|
||||
'header'=> "Content-type: application/x-www-form-urlencoded\r\nContent-Length: ".strlen($sData)."\r\n",
|
||||
));
|
||||
if ($sOptionnalHeaders !== null)
|
||||
{
|
||||
$aParams['http']['header'] .= $sOptionnalHeaders;
|
||||
}
|
||||
$ctx = stream_context_create($aParams);
|
||||
|
||||
$fp = @fopen($sUrl, 'rb', false, $ctx);
|
||||
if (!$fp)
|
||||
{
|
||||
throw new Exception("Problem with $sUrl, $php_errormsg");
|
||||
}
|
||||
$response = @stream_get_contents($fp);
|
||||
if ($response === false)
|
||||
{
|
||||
throw new Exception("Problem reading data from $sUrl, $php_errormsg");
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to execute a piece of code (checks if an error occurs)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
abstract class TestSoapWebService extends TestHandler
|
||||
{
|
||||
// simply overload DoExecute (temporary)
|
||||
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to check that a function outputs some values depending on its input
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
abstract class TestFunctionInOut extends TestFunction
|
||||
{
|
||||
abstract static public function GetCallSpec(); // parameters to call_user_func
|
||||
abstract static public function GetInOut(); // array of input => output
|
||||
|
||||
protected function DoExecute()
|
||||
{
|
||||
$aTests = $this->GetInOut();
|
||||
if (is_array($aTests))
|
||||
{
|
||||
foreach ($aTests as $iTestId => $aTest)
|
||||
{
|
||||
$ret = call_user_func_array($this->GetCallSpec(), $aTest['args']);
|
||||
if ($ret != $aTest['output'])
|
||||
{
|
||||
// Note: to be improved to cope with non string parameters
|
||||
$this->ReportError("Found '$ret' while expecting '".$aTest['output']."'", $iTestId);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->ReportSuccess("Found the expected output '$ret'", $iTestId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret = call_user_func($this->GetCallSpec());
|
||||
$this->ReportSuccess('Finished successfully');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test to check an URL (Searches for Error/Warning/Etc keywords)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
abstract class TestUrl extends TestHandler
|
||||
{
|
||||
abstract static public function GetUrl();
|
||||
abstract static public function GetErrorKeywords();
|
||||
abstract static public function GetWarningKeywords();
|
||||
|
||||
protected function DoExecute()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test to check a user management module
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
abstract class TestUserRights extends TestHandler
|
||||
{
|
||||
protected function DoExecute()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test to execute a scenario on a given DB
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
abstract class TestScenarioOnDB extends TestHandler
|
||||
{
|
||||
abstract static public function GetDBHost();
|
||||
abstract static public function GetDBUser();
|
||||
abstract static public function GetDBPwd();
|
||||
abstract static public function GetDBName();
|
||||
|
||||
protected function DoPrepare()
|
||||
{
|
||||
$sDBHost = $this->GetDBHost();
|
||||
$sDBUser = $this->GetDBUser();
|
||||
$sDBPwd = $this->GetDBPwd();
|
||||
$sDBName = $this->GetDBName();
|
||||
|
||||
CMDBSource::Init($sDBHost, $sDBUser, $sDBPwd);
|
||||
if (CMDBSource::IsDB($sDBName))
|
||||
{
|
||||
CMDBSource::DropDB($sDBName);
|
||||
}
|
||||
CMDBSource::CreateDB($sDBName);
|
||||
}
|
||||
|
||||
protected function DoCleanup()
|
||||
{
|
||||
// CMDBSource::DropDB($this->GetDBName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test to use a business model on a given DB
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
abstract class TestBizModel extends TestHandler
|
||||
{
|
||||
// abstract static public function GetDBSubName();
|
||||
// abstract static public function GetBusinessModelFile();
|
||||
abstract static public function GetConfigFile();
|
||||
|
||||
protected function DoPrepare()
|
||||
{
|
||||
MetaModel::Startup($this->GetConfigFile(), true); // allow missing DB
|
||||
MetaModel::CheckDefinitions();
|
||||
|
||||
// something here to create records... but that's another story
|
||||
}
|
||||
|
||||
protected $m_oChange;
|
||||
protected function ObjectToDB($oNew, $bReload = false)
|
||||
{
|
||||
list($bRes, $aIssues) = $oNew->CheckToInsert();
|
||||
if (!$bRes)
|
||||
{
|
||||
throw new CoreException('Could not create object, unexpected values', array('attributes' => $aIssues));
|
||||
}
|
||||
if ($oNew instanceof CMDBObject)
|
||||
{
|
||||
if (!isset($this->m_oChange))
|
||||
{
|
||||
new CMDBChange();
|
||||
$oMyChange = MetaModel::NewObject("CMDBChange");
|
||||
$oMyChange->Set("date", time());
|
||||
$oMyChange->Set("userinfo", "Someone doing some tests");
|
||||
$iChangeId = $oMyChange->DBInsertNoReload();
|
||||
$this->m_oChange = $oMyChange;
|
||||
}
|
||||
if ($bReload)
|
||||
{
|
||||
$iId = $oNew->DBInsertTracked($this->m_oChange);
|
||||
}
|
||||
else
|
||||
{
|
||||
$iId = $oNew->DBInsertTrackedNoReload($this->m_oChange);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($bReload)
|
||||
{
|
||||
$iId = $oNew->DBInsert();
|
||||
}
|
||||
else
|
||||
{
|
||||
$iId = $oNew->DBInsertNoReload();
|
||||
}
|
||||
}
|
||||
return $iId;
|
||||
}
|
||||
|
||||
protected function ResetDB()
|
||||
{
|
||||
if (MetaModel::DBExists(false))
|
||||
{
|
||||
MetaModel::DBDrop();
|
||||
}
|
||||
MetaModel::DBCreate();
|
||||
}
|
||||
|
||||
static protected function show_list($oObjectSet)
|
||||
{
|
||||
$oObjectSet->Rewind();
|
||||
$aData = array();
|
||||
while ($oItem = $oObjectSet->Fetch())
|
||||
{
|
||||
$aValues = array();
|
||||
foreach(MetaModel::GetAttributesList(get_class($oItem)) as $sAttCode)
|
||||
{
|
||||
$aValues[$sAttCode] = $oItem->GetAsHTML($sAttCode);
|
||||
}
|
||||
//echo $oItem->GetKey()." => ".implode(", ", $aValues)."</br>\n";
|
||||
$aData[] = $aValues;
|
||||
}
|
||||
echo MyHelpers::make_table_from_assoc_array($aData);
|
||||
}
|
||||
|
||||
static protected function search_and_show_list(DBObjectSearch $oMyFilter)
|
||||
{
|
||||
$oObjSet = new CMDBObjectSet($oMyFilter);
|
||||
echo $oMyFilter->__DescribeHTML()."' - Found ".$oObjSet->Count()." items.</br>\n";
|
||||
self::show_list($oObjSet);
|
||||
}
|
||||
|
||||
static protected function search_and_show_list_from_sibusql($sSibuSQL)
|
||||
{
|
||||
echo $sSibuSQL."...<br/>\n";
|
||||
$oNewFilter = DBObjectSearch::FromSibuSQL($sSibuSQL);
|
||||
self::search_and_show_list($oNewFilter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test to execute a scenario common to any business model (tries to build all the possible queries, etc.)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
abstract class TestBizModelGeneric extends TestBizModel
|
||||
{
|
||||
static public function GetName()
|
||||
{
|
||||
return 'Full test on a given business model';
|
||||
}
|
||||
|
||||
static public function GetDescription()
|
||||
{
|
||||
return 'Systematic tests: gets each and every existing class and tries every attribute, search filters, etc.';
|
||||
}
|
||||
|
||||
protected function DoPrepare()
|
||||
{
|
||||
parent::DoPrepare();
|
||||
|
||||
if (!MetaModel::DBExists(false))
|
||||
{
|
||||
MetaModel::DBCreate();
|
||||
}
|
||||
// something here to create records... but that's another story
|
||||
}
|
||||
|
||||
protected function DoExecute()
|
||||
{
|
||||
foreach(MetaModel::GetClasses() as $sClassName)
|
||||
{
|
||||
if (MetaModel::IsAbstract($sClassName)) continue;
|
||||
|
||||
$oNobody = MetaModel::GetObject($sClassName, 123);
|
||||
$oBaby = new $sClassName;
|
||||
$oFilter = new DBObjectSearch($sClassName);
|
||||
|
||||
// Challenge reversibility of SibusQL / filter object
|
||||
//
|
||||
$sExpr1 = $oFilter->ToSibuSQL();
|
||||
$oNewFilter = DBObjectSearch::FromSibuSQL($sExpr1);
|
||||
$sExpr2 = $oNewFilter->ToSibuSQL();
|
||||
if ($sExpr1 != $sExpr2)
|
||||
{
|
||||
$this->ReportError("Found two different SibuSQL expression out of the (same?) filter: <em>$sExpr1</em> != <em>$sExpr2</em>");
|
||||
}
|
||||
|
||||
// Use the filter (perform the query)
|
||||
//
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
$this->ReportSuccess('Found '.$oSet->Count()." objects of class $sClassName");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
274
core/trigger.class.inc.php
Normal file
274
core/trigger.class.inc.php
Normal file
@@ -0,0 +1,274 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* A user defined trigger, to customize the application
|
||||
* A trigger will activate an action
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
class Trigger extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "trigger",
|
||||
"description" => "Custom event handler",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "description",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_trigger",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "realclass",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("description", array("label"=>"Description", "description"=>"one line description", "allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("linked_actions", array("label"=>"Triggered actions", "description"=>"Actions performed when the trigger is activated", "linked_class"=>"lnkTriggerAction", "ext_key_to_me"=>"trigger_id", "ext_key_to_remote"=>"action_id", "allowed_values"=>null, "count_min"=>1, "count_max"=>0, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("description");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('finalclass', 'description')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
public function DoActivate($aContextArgs)
|
||||
{
|
||||
// Find the related
|
||||
$oLinkedActions = $this->Get('linked_actions');
|
||||
while ($oLink = $oLinkedActions->Fetch())
|
||||
{
|
||||
$iActionId = $oLink->Get('action_id');
|
||||
$oAction = MetaModel::GetObject('Action', $iActionId);
|
||||
if ($oAction->IsActive())
|
||||
{
|
||||
$oAction->DoExecute($this, $aContextArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TriggerOnObject extends Trigger
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "Trigger on a class of objects",
|
||||
"description" => "Trigger on a given class of objects",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_trigger_onobject",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeClass("target_class", array("label"=>"Target class", "description"=>"label", "class_category"=>"bizmodel", "more_values"=>null, "sql"=>"target_class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("target_class");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
|
||||
class TriggerOnStateChange extends TriggerOnObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "Trigger on object state change",
|
||||
"description" => "Trigger on object state change",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_trigger_onstatechange",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("state", array("label"=>"State", "description"=>"label", "allowed_values"=>null, "sql"=>"state", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
MetaModel::Init_AddFilterFromAttribute("state");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'state')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'state', 'description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
|
||||
class TriggerOnStateEnter extends TriggerOnStateChange
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "Trigger on object entering a state",
|
||||
"description" => "Trigger on object state change - entering",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_trigger_onstateenter",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'state')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('target_class', 'state', 'description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
|
||||
class TriggerOnStateLeave extends TriggerOnStateChange
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "Trigger on object leaving a state",
|
||||
"description" => "Trigger on object state change - leaving",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_trigger_onstateleave",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'state')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('target_class', 'state', 'description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
|
||||
class TriggerOnObjectCreate extends TriggerOnObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "Trigger on object creation",
|
||||
"description" => "Trigger on object creation of [a child class of] the given class",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_trigger_onobjcreate",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_InheritFilters();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
|
||||
class lnkTriggerAction extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "core/cmdb",
|
||||
"name" => "Actions-Trigger",
|
||||
"description" => "Link between a trigger and an action",
|
||||
"key_type" => "autoincrement",
|
||||
"key_label" => "Link ID",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(""),
|
||||
"db_table" => "priv_link_action_trigger",
|
||||
"db_key_field" => "link_id",
|
||||
"db_finalclass_field" => "",
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("action_id", array("targetclass"=>"Action", "jointype"=> '', "label"=>"Action", "description"=>"The action to be executed", "allowed_values"=>null, "sql"=>"action_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("action_name", array("label"=>"Action Name", "description"=>"Name of the action", "allowed_values"=>null, "extkey_attcode"=> 'action_id', "target_attcode"=>"name")));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("trigger_id", array("targetclass"=>"Trigger", "jointype"=> '', "label"=>"Trigger", "description"=>"Trigger", "allowed_values"=>null, "sql"=>"trigger_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("trigger_name", array("label"=>"Trigger Name", "description"=>"Name of the trigger", "allowed_values"=>null, "extkey_attcode"=> 'trigger_id', "target_attcode"=>"description")));
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("order", array("label"=>"Order", "description"=>"Actions execution order", "allowed_values"=>null, "sql"=>"order", "default_value"=>0, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddFilterFromAttribute("action_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("trigger_id");
|
||||
MetaModel::Init_AddFilterFromAttribute("order");
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('action_id', 'trigger_id', 'order')); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', array('action_name', 'trigger_name', 'order')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('action_id', 'trigger_id', 'order')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('advanced_search', array('action_id', 'trigger_id', 'order')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
?>
|
||||
306
core/userrights.class.inc.php
Normal file
306
core/userrights.class.inc.php
Normal file
@@ -0,0 +1,306 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UserRights
|
||||
* User management API
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
class UserRightException extends CoreException
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
define('UR_ALLOWED_NO', 0);
|
||||
define('UR_ALLOWED_YES', 1);
|
||||
define('UR_ALLOWED_DEPENDS', 2);
|
||||
|
||||
define('UR_ACTION_READ', 1); // View an object
|
||||
define('UR_ACTION_MODIFY', 2); // Create/modify an object/attribute
|
||||
define('UR_ACTION_DELETE', 3); // Delete an object
|
||||
|
||||
define('UR_ACTION_BULK_READ', 4); // Export multiple objects
|
||||
define('UR_ACTION_BULK_MODIFY', 5); // Create/modify multiple objects
|
||||
define('UR_ACTION_BULK_DELETE', 6); // Delete multiple objects
|
||||
|
||||
define('UR_ACTION_APPLICATION_DEFINED', 10000); // Application specific actions (CSV import, View schema...)
|
||||
|
||||
/**
|
||||
* User management module API
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
abstract class UserRightsAddOnAPI
|
||||
{
|
||||
abstract public function Setup(); // initial installation
|
||||
abstract public function CreateAdministrator($sAdminUser, $sAdminPwd); // could be used during initial installation
|
||||
|
||||
abstract public function Init(); // loads data (possible optimizations)
|
||||
abstract public function CheckCredentials($sLogin, $sPassword); // returns the id of the user or false
|
||||
abstract public function GetUserId($sLogin); // returns the id of the user or false
|
||||
abstract public function GetContactId($sLogin); // returns the id of the "business" user or false
|
||||
abstract public function GetFilter($sLogin, $sClass); // returns a filter object
|
||||
abstract public function IsActionAllowed($iUserId, $sClass, $iActionCode, /*dbObjectSet*/ $oInstanceSet = null);
|
||||
abstract public function IsStimulusAllowed($iUserId, $sClass, $sStimulusCode, /*dbObjectSet*/ $oInstanceSet = null);
|
||||
abstract public function IsActionAllowedOnAttribute($iUserId, $sClass, $sAttCode, $iActionCode, /*dbObjectSet*/ $oInstanceSet = null);
|
||||
abstract public function IsAdministrator($iUserId);
|
||||
abstract public function FlushPrivileges();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* User management core API
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class UserRights
|
||||
{
|
||||
protected static $m_oAddOn;
|
||||
protected static $m_sUser;
|
||||
protected static $m_sRealUser;
|
||||
protected static $m_iUserId;
|
||||
protected static $m_iRealUserId;
|
||||
|
||||
public static function SelectModule($sModuleName)
|
||||
{
|
||||
if (!class_exists($sModuleName))
|
||||
{
|
||||
throw new CoreException("Could not select this module, '$sModuleName' in not a valid class name");
|
||||
return;
|
||||
}
|
||||
if (!is_subclass_of($sModuleName, 'UserRightsAddOnAPI'))
|
||||
{
|
||||
throw new CoreException("Could not select this module, the class '$sModuleName' is not derived from UserRightsAddOnAPI");
|
||||
return;
|
||||
}
|
||||
self::$m_oAddOn = new $sModuleName;
|
||||
self::$m_oAddOn->Init();
|
||||
self::$m_sUser = '';
|
||||
self::$m_sRealUser = '';
|
||||
self::$m_iUserId = 0;
|
||||
self::$m_iRealUserId = 0;
|
||||
}
|
||||
|
||||
public static function GetModuleInstance()
|
||||
{
|
||||
return self::$m_oAddOn;
|
||||
}
|
||||
|
||||
// Installation: create the very first user
|
||||
public static function CreateAdministrator($sAdminUser, $sAdminPwd)
|
||||
{
|
||||
return self::$m_oAddOn->CreateAdministrator($sAdminUser, $sAdminPwd);
|
||||
}
|
||||
|
||||
// Installation (e.g: give default values for users)
|
||||
public static function Setup()
|
||||
{
|
||||
// to be discussed...
|
||||
return self::$m_oAddOn->Setup();
|
||||
}
|
||||
|
||||
protected static function IsLoggedIn()
|
||||
{
|
||||
return (!empty(self::$m_sUser));
|
||||
}
|
||||
|
||||
public static function Login($sName, $sPassword)
|
||||
{
|
||||
self::$m_iUserId = self::$m_oAddOn->CheckCredentials($sName, $sPassword);
|
||||
if ( self::$m_iUserId !== false )
|
||||
{
|
||||
self::$m_sUser = $sName;
|
||||
self::$m_iRealUserId = self::$m_iUserId;
|
||||
self::$m_sRealUser = $sName;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function Impersonate($sName, $sPassword)
|
||||
{
|
||||
if (!self::CheckLogin()) return false;
|
||||
|
||||
self::$m_iRealUserId = self::$m_oAddOn->CheckCredentials($sName, $sPassword);
|
||||
if ( self::$m_iRealUserId !== false)
|
||||
{
|
||||
self::$m_sUser = $sName;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function GetUser()
|
||||
{
|
||||
return self::$m_sUser;
|
||||
}
|
||||
|
||||
public static function GetUserId($sName = '')
|
||||
{
|
||||
if (empty($sName))
|
||||
{
|
||||
// return current user id
|
||||
return self::$m_iUserId;
|
||||
}
|
||||
else
|
||||
{
|
||||
// find the id out of the login string
|
||||
return self::$m_oAddOn->GetUserId($sName);
|
||||
}
|
||||
}
|
||||
|
||||
public static function GetContactId($sName = '')
|
||||
{
|
||||
// note: returns null if the user management module is not related to the business data model
|
||||
if (empty($sName))
|
||||
{
|
||||
$sName = self::$m_sUser;
|
||||
}
|
||||
return self::$m_oAddOn->GetContactId($sName);
|
||||
}
|
||||
|
||||
public static function GetRealUser()
|
||||
{
|
||||
return self::$m_sRealUser;
|
||||
}
|
||||
|
||||
public static function GetRealUserId()
|
||||
{
|
||||
return self::$m_iRealUserId;
|
||||
}
|
||||
|
||||
protected static function CheckLogin()
|
||||
{
|
||||
if (!self::IsLoggedIn())
|
||||
{
|
||||
//throw new UserRightException('No user logged in', array());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static function GetFilter($sClass)
|
||||
{
|
||||
if (!self::CheckLogin()) return false;
|
||||
if (self::IsAdministrator()) return new DBObjectSearch($sClass);
|
||||
|
||||
// this module is forbidden for non admins
|
||||
if (MetaModel::HasCategory($sClass, 'addon/userrights')) return false;
|
||||
|
||||
// the rest is allowed (#@# to be improved)
|
||||
if (!MetaModel::HasCategory($sClass, 'bizmodel')) return new DBObjectSearch($sClass);
|
||||
|
||||
return self::$m_oAddOn->GetFilter(self::$m_iUserId, $sClass);
|
||||
}
|
||||
|
||||
public static function IsActionAllowed($sClass, $iActionCode, /*dbObjectSet*/ $oInstanceSet = null, $iUserId = null)
|
||||
{
|
||||
if (!self::CheckLogin()) return false;
|
||||
if (self::IsAdministrator($iUserId)) return true;
|
||||
|
||||
// this module is forbidden for non admins
|
||||
if (MetaModel::HasCategory($sClass, 'addon/userrights')) return false;
|
||||
|
||||
// the rest is allowed (#@# to be improved)
|
||||
if (!MetaModel::HasCategory($sClass, 'bizmodel')) return true;
|
||||
|
||||
if (is_null($iUserId))
|
||||
{
|
||||
return self::$m_oAddOn->IsActionAllowed(self::$m_iUserId, $sClass, $iActionCode, $oInstanceSet);
|
||||
}
|
||||
else
|
||||
{
|
||||
return self::$m_oAddOn->IsActionAllowed($iUserId, $sClass, $iActionCode, $oInstanceSet);
|
||||
}
|
||||
}
|
||||
|
||||
public static function IsStimulusAllowed($sClass, $sStimulusCode, /*dbObjectSet*/ $oInstanceSet = null, $iUserId = null)
|
||||
{
|
||||
if (!self::CheckLogin()) return false;
|
||||
if (self::IsAdministrator($iUserId)) return true;
|
||||
|
||||
// this module is forbidden for non admins
|
||||
if (MetaModel::HasCategory($sClass, 'addon/userrights')) return false;
|
||||
|
||||
// the rest is allowed (#@# to be improved)
|
||||
if (!MetaModel::HasCategory($sClass, 'bizmodel')) return true;
|
||||
|
||||
if (is_null($iUserId))
|
||||
{
|
||||
return self::$m_oAddOn->IsStimulusAllowed(self::$m_iUserId, $sClass, $sStimulusCode, $oInstanceSet);
|
||||
}
|
||||
else
|
||||
{
|
||||
return self::$m_oAddOn->IsStimulusAllowed($iUserId, $sClass, $sStimulusCode, $oInstanceSet);
|
||||
}
|
||||
}
|
||||
|
||||
public static function IsActionAllowedOnAttribute($sClass, $sAttCode, $iActionCode, /*dbObjectSet*/ $oInstanceSet = null, $iUserId = null)
|
||||
{
|
||||
if (!self::CheckLogin()) return false;
|
||||
if (self::IsAdministrator($iUserId)) return true;
|
||||
|
||||
// this module is forbidden for non admins
|
||||
if (MetaModel::HasCategory($sClass, 'addon/userrights')) return false;
|
||||
|
||||
// the rest is allowed (#@# to be improved)
|
||||
if (!MetaModel::HasCategory($sClass, 'bizmodel')) return true;
|
||||
|
||||
if (is_null($iUserId))
|
||||
{
|
||||
return self::$m_oAddOn->IsActionAllowedOnAttribute(self::$m_iUserId, $sClass, $sAttCode, $iActionCode, $oInstanceSet);
|
||||
}
|
||||
else
|
||||
{
|
||||
return self::$m_oAddOn->IsActionAllowedOnAttribute($iUserId, $sClass, $sAttCode, $iActionCode, $oInstanceSet);
|
||||
}
|
||||
}
|
||||
|
||||
public static function IsAdministrator($iUserId = null)
|
||||
{
|
||||
if (!self::CheckLogin()) return false;
|
||||
|
||||
if (is_null($iUserId))
|
||||
{
|
||||
return self::$m_oAddOn->IsAdministrator(self::$m_iUserId);
|
||||
}
|
||||
else
|
||||
{
|
||||
return self::$m_oAddOn->IsAdministrator($iUserId);
|
||||
}
|
||||
}
|
||||
|
||||
public static function FlushPrivileges()
|
||||
{
|
||||
return self::$m_oAddOn->FlushPrivileges();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
195
core/valuesetdef.class.inc.php
Normal file
195
core/valuesetdef.class.inc.php
Normal file
@@ -0,0 +1,195 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ValueSetDefinition
|
||||
* value sets API and implementations
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @author Denis Flaven <denisflave@free.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version 1.1.1.1 $
|
||||
*/
|
||||
|
||||
require_once('MyHelpers.class.inc.php');
|
||||
|
||||
abstract class ValueSetDefinition
|
||||
{
|
||||
protected $m_bIsLoaded = false;
|
||||
protected $m_aValues = array();
|
||||
|
||||
|
||||
// Displayable description that could be computed out of the std usage context
|
||||
public function GetValuesDescription()
|
||||
{
|
||||
$aValues = $this->GetValues(array(), '');
|
||||
$aDisplayedValues = array();
|
||||
foreach($aValues as $key => $value)
|
||||
{
|
||||
$aDisplayedValues[] = "$key => $value";
|
||||
}
|
||||
$sAllowedValues = implode(', ', $aDisplayedValues);
|
||||
return $sAllowedValues;
|
||||
}
|
||||
|
||||
|
||||
public function GetValues($aArgs, $sBeginsWith)
|
||||
{
|
||||
if (!$this->m_bIsLoaded)
|
||||
{
|
||||
$this->LoadValues($aArgs);
|
||||
$this->m_bIsLoaded = true;
|
||||
}
|
||||
if (strlen($sBeginsWith) == 0)
|
||||
{
|
||||
$aRet = $this->m_aValues;
|
||||
}
|
||||
else
|
||||
{
|
||||
$iCheckedLen = strlen($sBeginsWith);
|
||||
$sBeginsWith = strtolower($sBeginsWith);
|
||||
$aRet = array();
|
||||
foreach ($this->m_aValues as $sKey=>$sValue)
|
||||
{
|
||||
if (strtolower(substr($sValue, 0, $iCheckedLen)) == $sBeginsWith)
|
||||
{
|
||||
$aRet[$sKey] = $sValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
abstract protected function LoadValues($aArgs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set of existing values for an attribute, given a search filter
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class ValueSetObjects extends ValueSetDefinition
|
||||
{
|
||||
protected $m_sFilterExpr; // in SibuSQL
|
||||
protected $m_sValueAttCode;
|
||||
protected $m_aOrderBy;
|
||||
|
||||
public function __construct($sFilterExp, $sValueAttCode = '', $aOrderBy = array())
|
||||
{
|
||||
$this->m_sFilterExpr = $sFilterExp;
|
||||
$this->m_sValueAttCode = $sValueAttCode;
|
||||
$this->m_aOrderBy = $aOrderBy;
|
||||
}
|
||||
|
||||
protected function LoadValues($aArgs)
|
||||
{
|
||||
$this->m_aValues = array();
|
||||
|
||||
$oFilter = DBObjectSearch::FromSibusQL($this->m_sFilterExpr, $aArgs);
|
||||
if (!$oFilter) return false;
|
||||
|
||||
if (empty($this->m_sValueAttCode))
|
||||
{
|
||||
$this->m_sValueAttCode = MetaModel::GetNameAttributeCode($oFilter->GetClass());
|
||||
}
|
||||
|
||||
$oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs);
|
||||
while ($oObject = $oObjects->Fetch())
|
||||
{
|
||||
$this->m_aValues[$oObject->GetKey()] = $oObject->GetAsHTML($this->m_sValueAttCode);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function GetValuesDescription()
|
||||
{
|
||||
return 'Filter: '.$this->m_sFilterExpr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fixed set values (could be hardcoded in the business model)
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class ValueSetEnum extends ValueSetDefinition
|
||||
{
|
||||
protected $m_values;
|
||||
|
||||
public function __construct($Values)
|
||||
{
|
||||
$this->m_values = $Values;
|
||||
}
|
||||
|
||||
protected function LoadValues($aArgs)
|
||||
{
|
||||
if (is_array($this->m_values))
|
||||
{
|
||||
$aValues = $this->m_values;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aValues = array();
|
||||
foreach (explode(",", $this->m_values) as $sVal)
|
||||
{
|
||||
$sVal = trim($sVal);
|
||||
$sKey = $sVal;
|
||||
$aValues[$sKey] = $sVal;
|
||||
}
|
||||
}
|
||||
$this->m_aValues = $aValues;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Data model classes
|
||||
*
|
||||
* @package iTopORM
|
||||
* @author Romain Quetiez <romainquetiez@yahoo.fr>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.itop.com
|
||||
* @since 1.0
|
||||
* @version $itopversion$
|
||||
*/
|
||||
class ValueSetEnumClasses extends ValueSetEnum
|
||||
{
|
||||
protected $m_sCategories;
|
||||
|
||||
public function __construct($sCategories = '', $sAdditionalValues = '')
|
||||
{
|
||||
$this->m_sCategories = $sCategories;
|
||||
parent::__construct($sAdditionalValues);
|
||||
}
|
||||
|
||||
protected function LoadValues($aArgs)
|
||||
{
|
||||
// First, get the additional values
|
||||
parent::LoadValues($aArgs);
|
||||
|
||||
// Then, add the classes from the category definition
|
||||
foreach (MetaModel::GetClasses($this->m_sCategories) as $sClass)
|
||||
{
|
||||
$this->m_aValues[$sClass] = MetaModel::GetName($sClass);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user