mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
Moved under "trunk" to be able to track releases under "tags"
SVN:trunk[55]
This commit is contained in:
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 web_page
|
||||
{
|
||||
/**
|
||||
* 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 trim($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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
12
application/application.inc.php
Normal file
12
application/application.inc.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?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/iotask.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');
|
||||
?>
|
||||
81
application/applicationcontext.class.inc.php
Normal file
81
application/applicationcontext.class.inc.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?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;
|
||||
|
||||
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()
|
||||
{
|
||||
$this->aValues = 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))
|
||||
{
|
||||
$this->aValues[$sName] = $sValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
?>
|
||||
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, "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
|
||||
}
|
||||
}
|
||||
?>
|
||||
647
application/cmdbabstract.class.inc.php
Normal file
647
application/cmdbabstract.class.inc.php
Normal file
@@ -0,0 +1,647 @@
|
||||
<?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 './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)
|
||||
{
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sExtClassNameAtt = MetaModel::GetNameAttributeCode($sObjClass);
|
||||
$sPage = self::ComputeUIPage($sObjClass);
|
||||
// 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);
|
||||
}
|
||||
$sHint = htmlentities("$sObjClass::$sObjKey");
|
||||
return "<a href=\"$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())
|
||||
{
|
||||
// retrieve the "external fields" linked to this external key
|
||||
$sTargetClass = $oAtt->GetTargetClass();
|
||||
$aAvailableFields = array();
|
||||
foreach (MetaModel::GetExternalFields(get_class($this), $sAttCode) as $oExtField)
|
||||
{
|
||||
$aAvailableFields[$oExtField->GetExtAttCode()] = $oExtField->GetAsHTML($this->Get($oExtField->GetCode()));
|
||||
}
|
||||
$sExtClassNameAtt = MetaModel::GetNameAttributeCode($sTargetClass);
|
||||
// Use the "name" of the target class as the label of the hyperlink
|
||||
// unless it's not available in the external fields...
|
||||
if (isset($aAvailableFields[$sExtClassNameAtt]))
|
||||
{
|
||||
$sDisplayValue = $aAvailableFields[$sExtClassNameAtt];
|
||||
}
|
||||
else
|
||||
{
|
||||
$sDisplayValue = implode(' / ', $aAvailableFields);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sDisplayValue = $this->GetAsHTML($sAttCode);
|
||||
}
|
||||
}
|
||||
return $sDisplayValue;
|
||||
}
|
||||
|
||||
function DisplayBareDetails(web_page $oPage)
|
||||
{
|
||||
$oPage->add($this->GetBareDetails($oPage));
|
||||
}
|
||||
|
||||
function GetDisplayName()
|
||||
{
|
||||
return $this->GetAsHTML(MetaModel::GetNameAttributeCode(get_class($this)));
|
||||
}
|
||||
|
||||
function GetBareDetails(web_page $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);
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
|
||||
function DisplayDetails(web_page $oPage)
|
||||
{
|
||||
$sTemplate = Utils::ReadFromFile(MetaModel::GetDisplayTemplate(get_class($this)));
|
||||
if (!empty($sTemplate))
|
||||
{
|
||||
$oTemplate = new DisplayTemplate($sTemplate);
|
||||
$oTemplate->Render($oPage, array('class'=> get_class($this),'pkey'=> $this->GetKey(), 'name' => $this->GetName()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Standard Header with name, actions menu and history block
|
||||
$oPage->add("<div class=\"page_header\">\n");
|
||||
$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");
|
||||
$oHistoryFilter = new DBObjectSearch('CMDBChangeOpSetAttribute');
|
||||
$oHistoryFilter->AddCondition('objkey', $this->GetKey());
|
||||
$oBlock = new HistoryBlock($oHistoryFilter, 'toggle', false);
|
||||
$oBlock->Display($oPage, -1);
|
||||
$oPage->add("</div>\n");
|
||||
|
||||
// Object's details
|
||||
// template not found display the object using the *old style*
|
||||
self::DisplayBareDetails($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);
|
||||
$this->DisplaySet($oPage, $oSet, $oAttDef->GetExtKeyToMe());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$oPage->SetCurrentTab('');
|
||||
}
|
||||
}
|
||||
|
||||
function DisplayPreview(web_page $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(web_page $oPage, CMDBObjectSet $oSet, $sLinkageAttribute = '')
|
||||
{
|
||||
$oPage->add(self::GetDisplaySet($oPage, $oSet, $sLinkageAttribute));
|
||||
}
|
||||
|
||||
public static function GetDisplaySet(web_page $oPage, CMDBObjectSet $oSet, $sLinkageAttribute = '', $bDisplayMenu = true)
|
||||
{
|
||||
$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;
|
||||
}
|
||||
foreach($aList as $sAttCode)
|
||||
{
|
||||
$aAttribs['key'] = array('label' => '', 'description' => 'Click to display');
|
||||
$aAttribs[$sAttCode] = array('label' => MetaModel::GetLabel($sClassName, $sAttCode), 'description' => MetaModel::GetDescription($sClassName, $sAttCode));
|
||||
}
|
||||
$aValues = array();
|
||||
$oSet->Seek(0);
|
||||
while ($oObj = $oSet->Fetch())
|
||||
{
|
||||
$aRow['key'] = $oObj->GetKey();
|
||||
foreach($aList as $sAttCode)
|
||||
{
|
||||
$aRow[$sAttCode] = $oObj->GetAsHTML($sAttCode);
|
||||
}
|
||||
$aValues[] = $aRow;
|
||||
}
|
||||
$oMenuBlock = new MenuBlock($oSet->GetFilter());
|
||||
$sHtml .= '<table class="listContainer">';
|
||||
if ($bDisplayMenu)
|
||||
{
|
||||
$sHtml .= '<tr class="containerHeader"><td>';
|
||||
$sHtml .= $oMenuBlock->GetRenderContent($oPage, $sLinkageAttribute);
|
||||
$sHtml .= '</td></tr>';
|
||||
}
|
||||
$sHtml .= '<tr><td>';
|
||||
$sHtml .= $oPage->GetTable($aAttribs, $aValues, array('class'=>$sClassName, 'filter'=>$oSet->GetFilter()->serialize(), 'preview' => true));
|
||||
$sHtml .= '</td></tr>';
|
||||
$sHtml .= '</table>';
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
static function DisplaySetAsCSV(web_page $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)
|
||||
{
|
||||
if (strstr($oObj->Get($sAttCode), $sSeparator)) // Escape the text only when it contains the separator
|
||||
{
|
||||
$aRow[] = $sTextQualifier.$oObj->Get($sAttCode).$sTextQualifier;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aRow[] = $oObj->Get($sAttCode);
|
||||
}
|
||||
}
|
||||
$sHtml .= implode($sSeparator, $aRow)."\n";
|
||||
}
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
static function DisplaySetAsXML(web_page $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())
|
||||
{
|
||||
$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(web_page $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(web_page $oPage, CMDBObjectSet $oSet, $aExtraParams = array())
|
||||
{
|
||||
|
||||
$oPage->add(self::GetSearchForm($oPage, $oSet, $aExtraParams));
|
||||
}
|
||||
|
||||
public static function GetSearchForm(web_page $oPage, CMDBObjectSet $oSet, $aExtraParams = array())
|
||||
{
|
||||
$sHtml = '';
|
||||
$numCols=4;
|
||||
$sClassName = $oSet->GetFilter()->GetClass();
|
||||
$oUnlimitedFilter = new DBObjectSearch($sClassName);
|
||||
$sHtml .= "<form>\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)
|
||||
{
|
||||
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, array(), '');
|
||||
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=\"dosearch\" value=\"1\">\n";
|
||||
$sHtml .= "</form>\n";
|
||||
// Soem Debug dumps...
|
||||
//$sHtml .= "<tt>".$oSet->GetFilter()->__DescribeHTML()."</tt><br/>\n";
|
||||
//$sHtml .= "<tt>encoding=\"text/serialize\" : ".$oSet->GetFilter()->serialize()."</tt><br/>\n";
|
||||
//$sHtml .= "<tt>encoding=\"text/sibusql\" : ".$oSet->GetFilter()->ToSibusQL()."</tt><br/>\n";
|
||||
//$sHtml .= "<tt>(Unlimited) ".$oUnlimitedFilter->__DescribeHTML()."</tt><br/>\n";
|
||||
//$sHtml .= "<tt>encoding=\"text/serialize\" : ".$oUnlimitedFilter->serialize()."</tt><br/>\n";
|
||||
//$sHtml .= "<tt>encoding=\"text/sibusql\" : ".$oUnlimitedFilter->ToSibusQL()."</tt>\n";
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
public static function GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $value = '', $sDisplayValue = '', $iId = '')
|
||||
{
|
||||
static $iInputId = 0;
|
||||
if (!empty($iId))
|
||||
{
|
||||
$iInputId = $iId;
|
||||
}
|
||||
else
|
||||
{
|
||||
$iInputId++;
|
||||
}
|
||||
if (!$oAttDef->IsExternalField())
|
||||
{
|
||||
switch($oAttDef->GetEditClass())
|
||||
{
|
||||
case 'Date':
|
||||
$sHTMLValue = "<input type=\"text\" size=\"20\" name=\"attr_$sAttCode\" value=\"$value\" id=\"$iInputId\" class=\"date-pick\"/>";
|
||||
break;
|
||||
|
||||
case 'Text':
|
||||
$sHTMLValue = "<textarea name=\"attr_$sAttCode\" rows=\"8\" cols=\"40\" id=\"$iInputId\">$value</textarea>";
|
||||
break;
|
||||
|
||||
case 'List':
|
||||
$oWidget = new UILinksWidget($sClass, $sAttCode, $iInputId);
|
||||
$sHTMLValue = $oWidget->Display($oPage, $value);
|
||||
break;
|
||||
|
||||
case 'String':
|
||||
default:
|
||||
$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, array(), '');
|
||||
if ($aAllowedValues !== null)
|
||||
{
|
||||
//Enum field or external key, display a combo
|
||||
if (count($aAllowedValues) == 0)
|
||||
{
|
||||
$sHTMLValue = "<input type=\"text\" size=\"70\" value=\"\" name=\"attr_$sAttCode\" id=\"$iInputId\"/>";
|
||||
}
|
||||
else if (count($aAllowedValues) > 20)
|
||||
{
|
||||
// too many choices, use an autocomplete
|
||||
// The input for the auto complete
|
||||
$sHTMLValue = "<input type=\"text\" id=\"$iInputId\" size=\"50\" name=\"\" value=\"$sDisplayValue\" />";
|
||||
// another hidden input to store & pass the object's Id
|
||||
$sHTMLValue .= "<input type=\"hidden\" id=\"id_ac_$iInputId\" name=\"attr_$sAttCode\" value=\"$value\" />\n";
|
||||
$oPage->add_ready_script("\$('#$iInputId').autocomplete('./ajax.render.php', { minChars:3, onItemSelect:selectItem, onFindValue:findValue, formatItem:formatItem, autoFill:true, keyHolder:'#id_ac_$iInputId', extraParams:{operation:'autocomplete', sclass:'$sClass',attCode:'".$sAttCode."'}});");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Few choices, use a normal 'select'
|
||||
$sHTMLValue = "<select name=\"attr_$sAttCode\" id=\"$iInputId\">\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=\"50\" name=\"attr_$sAttCode\" value=\"$value\" id=\"$iInputId\">";
|
||||
}
|
||||
}
|
||||
}
|
||||
return $sHTMLValue;
|
||||
}
|
||||
|
||||
public function DisplayModifyForm(web_page $oPage)
|
||||
{
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode(get_class($this));
|
||||
$iKey = $this->GetKey();
|
||||
$aDetails = array();
|
||||
$oPage->add("<form method=\"post\">\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);
|
||||
$sHTMLValue = self::GetFormElementForField($oPage, get_class($this), $sAttCode, $oAttDef, $sValue, $sDisplayValue);
|
||||
}
|
||||
$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(web_page $oPage, $sClass, $oObjectToClone = null)
|
||||
{
|
||||
$oAppContext = new ApplicationContext();
|
||||
$aDetails = array();
|
||||
$sOperation = ($oObjectToClone == null) ? 'apply_new' : 'apply_clone';
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode(get_class($oObjectToClone));
|
||||
$oPage->add("<form method=\"post\">\n");
|
||||
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);
|
||||
$sHTMLValue = self::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue);
|
||||
$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");
|
||||
}
|
||||
}
|
||||
?>
|
||||
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 web_page
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
?>
|
||||
686
application/displayblock.class.inc.php
Normal file
686
application/displayblock.class.inc.php
Normal file
@@ -0,0 +1,686 @@
|
||||
<?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);
|
||||
|
||||
if (($iStartPos === false) || ($iEndPos === false)) return null; // invalid template
|
||||
$sITopBlock = substr($sTemplate,$iStartPos, $iEndPos-$iStartPos);
|
||||
$sITopData = substr($sITopBlock, 1+stripos($sITopBlock, ">"));
|
||||
$sITopTag = substr($sITopBlock, 0, stripos($sITopBlock, ">"));
|
||||
$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('/ linkage="(.*)"/U',$sITopTag, $aMatches))
|
||||
{
|
||||
// The list to display is a list of links to the specified object
|
||||
$sExtKey = strtolower($aMatches[1]);
|
||||
$aParams['linkage'] = $sExtKey; // Name of the Ext. Key that make this linkage
|
||||
}
|
||||
// Parameters contains a list of extra parameters for the block
|
||||
// the syntax is param_name1:value1;param_name2:value2;...
|
||||
$aParams = array();
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
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(web_page $oPage, $sId, $aExtraParams = array())
|
||||
{
|
||||
$aExtraParams = array_merge($aExtraParams, $this->m_aParams);
|
||||
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(web_page $oPage, $sId, $aExtraParams = array())
|
||||
{
|
||||
$sHtml = '';
|
||||
$aExtraParams = array_merge($aExtraParams, $this->m_aParams);
|
||||
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
|
||||
$sFilter = $this->m_oFilter->serialize();
|
||||
$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" },
|
||||
function(data){
|
||||
$("#'.$sId.'").empty();
|
||||
$("#'.$sId.'").append(data);
|
||||
$("#'.$sId.'").removeClass("loading");
|
||||
}
|
||||
);
|
||||
</script>'; // TO DO: add support for $aExtraParams in asynchronous/Ajax mode
|
||||
}
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
public function RenderContent(web_page $oPage, $aExtraParams = array())
|
||||
{
|
||||
$oPage->add($this->GetRenderContent($oPage, $aExtraParams));
|
||||
}
|
||||
|
||||
public function GetRenderContent(web_page $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)
|
||||
{
|
||||
$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->Get($sGroupByField);
|
||||
$aGroupBy[$sValue] = isset($aGroupBy[$sValue]) ? $aGroupBy[$sValue]+1 : 1;
|
||||
}
|
||||
$sFilter = urlencode($this->m_oFilter->serialize());
|
||||
$aData = array();
|
||||
foreach($aGroupBy as $sValue => $iCount)
|
||||
{
|
||||
$aData[] = array ( 'group' => $sValue,
|
||||
'value' => "<a href=\"./UI.php?operation=search&dosearch=1&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':
|
||||
$bDashboardMode = isset($aExtraParams['dashboard']) ? ($aExtraParams['dashboard'] == 'true') : false;
|
||||
if ( ($this->m_oSet->Count()> 0) && (UserRights::IsActionAllowed($this->m_oSet->GetClass(), UR_ACTION_READ, $this->m_oSet) == UR_ALLOWED_YES) )
|
||||
{
|
||||
if (!$bDashboardMode)
|
||||
{
|
||||
$sHtml .= $oPage->GetP($this->m_oSet->Count()." object(s).");
|
||||
}
|
||||
$sLinkage = isset($aExtraParams['linkage']) ? $aExtraParams['linkage'] : '';
|
||||
$sHtml .= cmdbAbstractObject::GetDisplaySet($oPage, $this->m_oSet, $sLinkage, !$bDashboardMode /* bDisplayMenu */);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml .= $oPage->GetP("No object to display.");
|
||||
$sClass = $this->m_oFilter->GetClass();
|
||||
if (!$bDashboardMode)
|
||||
{
|
||||
if (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $this->m_oSet) == UR_ALLOWED_YES)
|
||||
{
|
||||
$sHtml .= $oPage->GetP("<a href=\"./UI.php?operation=new&class=$sClass\">Click here to create a new ".Metamodel::GetName($sClass)."</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);
|
||||
}
|
||||
}
|
||||
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:100%;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";
|
||||
$sHtml .= "<h1>Search form for ".Metamodel::GetName($this->m_oSet->GetClass())."</h1>\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}\">Here goes the chart</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(web_page $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':
|
||||
$oLatestChangeOp = $oSet->Fetch();
|
||||
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->Load(); // Reset the pointer to the beginning of the set: there should be a better way to do this...
|
||||
$sHtml .= $oPage->GetStartCollapsibleSection("Last modified on $sDate by $sUserInfo.");
|
||||
$sHtml .= cmdbAbstractObject::GetDisplaySet($oPage, $oSet);
|
||||
$sHtml .= $oPage->GetEndCollapsibleSection();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$sHtml .= parent::GetRenderContent($oPage, $aExtraParams);
|
||||
}
|
||||
return $sHtml;
|
||||
}
|
||||
}
|
||||
|
||||
class MenuBlock extends DisplayBlock
|
||||
{
|
||||
public function GetRenderContent(web_page $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);
|
||||
switch($oSet->Count())
|
||||
{
|
||||
case 0:
|
||||
// No object in the set, the only possible action is "new"
|
||||
$bIsModifyAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet);
|
||||
if ($bIsModifyAllowed) { $aActions[] = array ('label' => 'New', 'url' => "../page/$sUIPage?operation=new&class=$sClass&$sContext"); }
|
||||
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['linkage']))
|
||||
{
|
||||
if ($bIsModifyAllowed) { $aActions[] = array ('label' => 'New...', 'url' => "#"); }
|
||||
if ($bIsBulkModifyAllowed) { $aActions[] = array ('label' => 'Modify All...', 'url' => "#"); }
|
||||
if ($bIsBulkDeleteAllowed) { $aActions[] = array ('label' => 'Remove All', 'url' => "#"); }
|
||||
if ($bIsModifyAllowed | $bIsDeleteAllowed) { $aActions[] = array ('label' => 'Manage Links...', 'url' => "#"); }
|
||||
}
|
||||
else
|
||||
{
|
||||
$aActions[] = array ('label' => 'eMail', 'url' => "mailto:?subject=".$oSet->GetFilter()->__DescribeHTML()."&body=".urlencode("http://localhost:81/pages/UI.php?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"); }
|
||||
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['linkage']))
|
||||
{
|
||||
$bIsDeleteAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_DELETE, $oSet);
|
||||
if ($bIsModifyAllowed) { $aActions[] = array ('label' => 'New...', 'url' => "#"); }
|
||||
if ($bIsBulkModifyAllowed) { $aActions[] = array ('label' => 'Modify All...', 'url' => "#"); }
|
||||
if ($bIsBulkDeleteAllowed) { $aActions[] = array ('label' => 'Remove All', 'url' => "#"); }
|
||||
if ($bIsModifyAllowed | $bIsDeleteAllowed) { $aActions[] = array ('label' => 'Manage Links...', 'url' => "#"); }
|
||||
}
|
||||
else
|
||||
{
|
||||
// many objects in the set, possible actions are: new / modify all / delete all
|
||||
$aActions[] = array ('label' => 'eMail', 'url' => "mailto:?subject=".$oSet->GetFilter()->__DescribeHTML()."&body=".urlencode("http://localhost:81/pages/UI.php?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"); }
|
||||
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 AttributeEnum("objects_class", array("label"=>"Objects Class", "description"=>"Class of the objects processed by this task", "allowed_values"=>new ValueSetEnum('bizOrganization, bizContact, bizTeam, bizPerson, bizLocation, bizServer, bizPC, bizNetworkDevice, bizInterface, bizService, bizContract, bizInfraGroup, bizIncidentTicket, bizSoftware, bizApplication, bizPatch, bizWorkgroup, lnkContactRealObject, lnkInterfaces, bizInfraGrouping' ), "sql"=>"objects_class", "default_value"=>'', "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
|
||||
}
|
||||
}
|
||||
?>
|
||||
414
application/itopwebpage.class.inc.php
Normal file
414
application/itopwebpage.class.inc.php
Normal file
@@ -0,0 +1,414 @@
|
||||
<?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 nice_web_page
|
||||
{
|
||||
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/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\"><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></form>\n");
|
||||
$this->AddToMenu("</div>\n");
|
||||
$this->AddToMenu("<ul id=\"browser\" class=\"dir\">\n");
|
||||
$oAppContext = new ApplicationContext();
|
||||
// Display the menu
|
||||
// 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());
|
||||
}
|
||||
$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";
|
||||
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";
|
||||
}
|
||||
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 "<link rel=\"search\" type=\"application/opensearchdescription+xml\" title=\"iTop\" href=\"./opensearch.xml.php\">\n";
|
||||
echo "</head>\n";
|
||||
echo "<body>\n";
|
||||
|
||||
// Display the header
|
||||
echo "<div id=\"Header\">\n";
|
||||
echo "<div class=\"iTopLogo\"><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;\"";
|
||||
}
|
||||
echo "<div id=\"OrganizationSelection\" style=\"position:absolute; top:18px; right:16px; width:400px;\">";
|
||||
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 "<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;
|
||||
$sHtml .= "<a id=\"LnkCollapse_$iSectionId\" class=\"CollapsibleLabel\" 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();
|
||||
}
|
||||
}
|
||||
?>
|
||||
117
application/loginwebpage.class.inc.php
Normal file
117
application/loginwebpage.class.inc.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
require_once("../application/nicewebpage.class.inc.php");
|
||||
/**
|
||||
* Web page used for displaying the login form
|
||||
*/
|
||||
class login_web_page extends nice_web_page
|
||||
{
|
||||
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=\"operation\" value=\"login\" />\n");
|
||||
$this->add("</form>\n");
|
||||
$this->add("</div>\n");
|
||||
}
|
||||
|
||||
static function DoLogin()
|
||||
{
|
||||
$operation = utils::ReadParam('operation', '');
|
||||
session_start();
|
||||
|
||||
if (!session_is_registered('auth_user') || !session_is_registered('auth_pwd'))
|
||||
{
|
||||
if ($operation == 'login')
|
||||
{
|
||||
$sAuthUser = utils::ReadParam('auth_user', '', 'post');
|
||||
$sAuthPwd = utils::ReadParam('auth_pwd', '', 'post');
|
||||
}
|
||||
else
|
||||
{
|
||||
$oPage = new login_web_page();
|
||||
$oPage->DisplayLoginForm();
|
||||
$oPage->output();
|
||||
exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sAuthUser = $_SESSION['auth_user'];
|
||||
$sAuthPwd = $_SESSION['auth_pwd'];
|
||||
}
|
||||
if (!UserRights::Login($sAuthUser, $sAuthPwd))
|
||||
{
|
||||
// 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();
|
||||
|
||||
$oPage = new login_web_page();
|
||||
$oPage->DisplayLoginForm( true /* failed attempt */);
|
||||
$oPage->output();
|
||||
exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
$_SESSION['auth_user'] = $sAuthUser ;
|
||||
$_SESSION['auth_pwd'] = $sAuthPwd;
|
||||
|
||||
}
|
||||
}
|
||||
} // End of class
|
||||
?>
|
||||
219
application/menunode.class.inc.php
Normal file
219
application/menunode.class.inc.php
Normal file
@@ -0,0 +1,219 @@
|
||||
<?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, "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'), "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, "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 AttributeExternalKey("user_id", array("label"=>"Owner of the menu", "description"=>"User who owns this menu (for user defined menus)", "allowed_values"=>null, "sql"=>"user_id", "targetclass"=>"UserRightsMatrixUsers", "is_null_allowed"=>true, "depends_on"=>array('type'))));
|
||||
|
||||
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)
|
||||
{
|
||||
$oSearchFilter = new DBObjectSearch("menuNode");
|
||||
$oSearchFilter->AddCondition('parent_id', $this->GetKey(), '=');
|
||||
$oSearchFilter->AddCondition('type', $sType, '=');
|
||||
if ($sType == 'user')
|
||||
{
|
||||
$oSearchFilter->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||
}
|
||||
$oSet = new CMDBObjectSet($oSearchFilter, array('rank' => true));
|
||||
return $oSet;
|
||||
}
|
||||
|
||||
public function RenderContent(web_page $oPage, $aExtraParams = array())
|
||||
{
|
||||
$sTemplate = $this->Get('template');
|
||||
$this->ProcessTemplate($sTemplate, $oPage, $aExtraParams);
|
||||
}
|
||||
|
||||
protected function ProcessTemplate($sTemplate, web_page $oPage, $aExtraParams = array())
|
||||
{
|
||||
$iStartPos = stripos($sTemplate, '<'.DisplayBlock::TAG_BLOCK.' ',0);
|
||||
$index = 0;
|
||||
while(($iStartPos = stripos($sTemplate, '<'.DisplayBlock::TAG_BLOCK.' ',0)) !== false)
|
||||
{
|
||||
$iEndPos = stripos($sTemplate, '</'.DisplayBlock::TAG_BLOCK.'>', $iStartPos);
|
||||
|
||||
$sBlockDefinition = substr($sTemplate, $iStartPos, $iEndPos - $iStartPos + strlen('</'.DisplayBlock::TAG_BLOCK.'>'));
|
||||
$oBlock = DisplayBlock::FromTemplate($sBlockDefinition);
|
||||
|
||||
$oPage->add(substr($sTemplate, 0, $iStartPos));
|
||||
if ($oBlock) // Protects agains invalid XML templates
|
||||
{
|
||||
$oBlock->Display($oPage, "block{$index}", $aExtraParams); // Values from $aExtraParams have precedence over $aParams
|
||||
}
|
||||
$index++;
|
||||
$sTemplate = substr($sTemplate, $iEndPos + strlen('</'.DisplayBlock::TAG_BLOCK.'>'));
|
||||
}
|
||||
// What remains is purely static (without any block inside), just output as it is
|
||||
$oPage->add($sTemplate);
|
||||
}
|
||||
|
||||
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(web_page $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, '=');
|
||||
$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'), '>');
|
||||
$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;
|
||||
}
|
||||
}
|
||||
?>
|
||||
76
application/nicewebpage.class.inc.php
Normal file
76
application/nicewebpage.class.inc.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
require_once("../application/webpage.class.inc.php");
|
||||
/**
|
||||
* Web page with some associated CSS and scripts (jquery) for a fancier display
|
||||
*/
|
||||
class nice_web_page extends web_page
|
||||
{
|
||||
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)
|
||||
{
|
||||
// $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)
|
||||
{
|
||||
$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();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
7
application/startup.inc.php
Normal file
7
application/startup.inc.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?
|
||||
|
||||
require_once('../application/utils.inc.php');
|
||||
|
||||
MetaModel::Startup('../config-itop.php');
|
||||
|
||||
?>
|
||||
224
application/template.class.inc.php
Normal file
224
application/template.class.inc.php
Normal file
@@ -0,0 +1,224 @@
|
||||
<?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;
|
||||
|
||||
public function __construct($sTemplate)
|
||||
{
|
||||
$this->m_aTags = array('itopblock', 'itoptabs', 'itoptab', 'itoptoggle');
|
||||
$this->m_sTemplate = $sTemplate;
|
||||
}
|
||||
|
||||
public function Render(web_page $oPage, $aParams = array())
|
||||
{
|
||||
$this->ApplyParams($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);
|
||||
$aAttributes = $this->GetTagAttributes($sTag, $iStart, $iEnd);
|
||||
//$oPage->p("Tag: $sTag - ($iStart, $iEnd)");
|
||||
$oPage->add(substr($this->m_sTemplate, $iBeforeTagPos, $iStart - $iBeforeTagPos));
|
||||
$this->RenderTag($oPage, $sTag, $aAttributes, $sContent);
|
||||
|
||||
$iAfterTagPos = $iEnd + strlen('</'.$sTag.'>');
|
||||
$iBeforeTagPos = $iAfterTagPos;
|
||||
$iStart = $iEnd;
|
||||
$iEnd = strlen($this->m_sTemplate);
|
||||
$iCount++;
|
||||
if ($iCount > 10) break;
|
||||
}
|
||||
$oPage->add(substr($this->m_sTemplate, $iAfterTagPos));
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces all the parameters by the values passed in the hash array
|
||||
*/
|
||||
public function ApplyParams($aParams)
|
||||
{
|
||||
$aSearches = array();
|
||||
$aReplacements = array();
|
||||
foreach($aParams as $sSearch => $sReplace)
|
||||
{
|
||||
$aSearches[] = '$'.$sSearch.'$';
|
||||
$aReplacements[] = $sReplace;
|
||||
}
|
||||
$this->m_sTemplate = str_replace($aSearches, $aReplacements, $this->m_sTemplate);
|
||||
}
|
||||
|
||||
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;
|
||||
static $iBlockCount = 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($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':
|
||||
$oPage->StartCollapsibleSection($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->EndCollapsibleSection();
|
||||
break;
|
||||
|
||||
case 'itopblock': // TO DO: Use DisplayBlock::FromTemplate here
|
||||
$sBlockClass = $aAttributes['blockclass'];
|
||||
$sBlockType = $aAttributes['type'];
|
||||
$aExtraParams = array();
|
||||
if (isset($aAttributes['linkage']))
|
||||
{
|
||||
$aExtraParams['linkage'] = $aAttributes['linkage'];
|
||||
}
|
||||
|
||||
switch($aAttributes['encoding'])
|
||||
{
|
||||
case 'text/sibusql':
|
||||
$oFilter = CMDBSearchFilter::FromSibusQL($sContent);
|
||||
break;
|
||||
|
||||
case 'text/oql':
|
||||
$oFilter = CMDBSearchFilter::FromOQL($sContent);
|
||||
break;
|
||||
|
||||
case 'text/serialize':
|
||||
default:
|
||||
$oFilter = CMDBSearchFilter::unserialize($sContent);
|
||||
break;
|
||||
}
|
||||
$oBlock = new $sBlockClass($oFilter, $sBlockType, false, $aExtraParams);
|
||||
$oBlock->Display($oPage, 'block_'.$iBlockCount);
|
||||
$iBlockCount++;
|
||||
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/sibusql">CMDBChangeOpSetAttribute: objkey = $pkey$</itopblock>
|
||||
</div>
|
||||
<img src="../../images/connect_to_network.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="true" 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 CMDBChangeOpSetAttribute 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="true" 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>
|
||||
301
application/ui.linkswidget.class.inc.php
Normal file
301
application/ui.linkswidget.class.inc.php
Normal file
@@ -0,0 +1,301 @@
|
||||
<?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_iInputId;
|
||||
|
||||
public function __construct($sClass, $sAttCode, $iInputId)
|
||||
{
|
||||
$this->m_sClass = $sClass;
|
||||
$this->m_sAttCode = $sAttCode;
|
||||
$this->m_iInputId = $iInputId;
|
||||
}
|
||||
|
||||
public function Display(web_page $oPage, $oCurrentValuesSet = null)
|
||||
{
|
||||
$sHTMLValue = '';
|
||||
$sTargetClass = self::GetTargetClass($this->m_sClass, $this->m_sAttCode);
|
||||
$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);
|
||||
|
||||
$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();
|
||||
$sRow = '{';
|
||||
while($oLinkObj = $oCurrentValuesSet->Fetch())
|
||||
{
|
||||
foreach($aAttributes as $sLinkAttCode)
|
||||
{
|
||||
$sRow.= "\"$sLinkAttCode\": \"".addslashes($oLinkObj->Get($sLinkAttCode))."\", ";
|
||||
}
|
||||
$sRow .= "\"$sExtKeyToRemote\": ".$oLinkObj->Get($sExtKeyToRemote).'}';
|
||||
$aCurrentValues[] = $sRow;
|
||||
}
|
||||
$sJSON = '['.implode(',', $aCurrentValues).']';
|
||||
}
|
||||
|
||||
// Many values (or even a unknown list) display an autocomplete
|
||||
if ( (count($aAllowedValues) == 0) || (count($aAllowedValues) > 20) )
|
||||
{
|
||||
// too many choices, use an autocomplete
|
||||
// The input for the auto complete
|
||||
$sTitle = $oAttDef->GetDescription();
|
||||
$sHTMLValue .= "<script>\n";
|
||||
$sHTMLValue .= "oLinkWidget{$this->m_iInputId} = new LinksWidget('{$this->m_iInputId}', '$sLinkedClass', '$sExtKeyToMe', '$sExtKeyToRemote', $sAttributes);\n";
|
||||
$sHTMLValue .= "</script>\n";
|
||||
$sHTMLValue .= $this->GetObjectPickerDialog($oPage, $sTargetClass, 'oLinkWidget'.$this->m_iInputId.'.OnOk');
|
||||
$sHTMLValue .= $this->GetLinkObjectDialog($oPage, $this->m_iInputId);
|
||||
$sHTMLValue .= "<input type=\"text\" id=\"ac_{$this->m_iInputId}\" size=\"35\" name=\"\" value=\"\" style=\"border: 1px solid red;\" />";
|
||||
$sHTMLValue .= "<input type=\"button\" 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}\"/>\n";
|
||||
$sHTMLValue .= "<input type=\"hidden\" id=\"{$this->m_iInputId}\" name=\"attr_{$this->m_sAttCode}\" value=\"\"/>\n";
|
||||
$oPage->add_ready_script("\$('#{$this->m_iInputId}').val('$sJSON');\n\$('#ac_{$this->m_iInputId}').autocomplete('./ajax.render.php', { 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}});");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Few choices, use a normal 'select'
|
||||
$sHTMLValue = "<select name=\"attr_{$this->m_sAttCode}\" id=\"{$this->m_iInputId}\">\n";
|
||||
|
||||
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);
|
||||
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));
|
||||
}
|
||||
}
|
||||
$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 web_page 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(web_page $oPage, UserContext $oContext, $sClass, $sAttCode, $sName, $iMaxCount)
|
||||
{
|
||||
$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 web_page The ajax page used for the put^put (sent back to the browser
|
||||
* @param $sClass string The name of the class 'linking class' which is the class of the objects to display
|
||||
* @param $sAttCode string The name of the attribute is the main object being created
|
||||
* @param $sSet JSON serialized set of objects
|
||||
* @return void
|
||||
*/
|
||||
static public function RenderSet($oPage, $sClass, $sJSONSet, $sExtKeyToMe)
|
||||
{
|
||||
$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);
|
||||
}
|
||||
cmdbAbstractObject::DisplaySet($oPage, $oSet, $sExtKeyToMe);
|
||||
}
|
||||
|
||||
|
||||
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="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">
|
||||
<button type="button" class="jqmClose" onClick="$('#ManageObjectsDlg_{$this->m_iInputId}').jqmHide(); $sOkFunction('$sTargetClass', 'selected_objects')"> Ok </button> <button type="button" class="jqmClose"> Cancel</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</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=\"page_header\"><h1 id=\"LinkObject_DlgTitle\">$sLinkedClass attributes</h1></div>\n";
|
||||
$sHTML .= "<form>\n";
|
||||
$index = 0;
|
||||
$aAttrsMap = 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);
|
||||
}
|
||||
$aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
$sHTML .= $oPage->GetDetails($aDetails);
|
||||
$sHTML .= "<button type=\"button\" class=\"jqmClose\" onClick=\"oLinkWidget$sId.OnLinkOk()\"> Ok </button> <button type=\"button\" class=\"jqmClose\" onClick=\"LinkWidget$sId.OnLinkCancel()\"> Cancel</button>\n";
|
||||
$sHTML .= "</form>\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;
|
||||
}
|
||||
}
|
||||
?>
|
||||
257
application/uiwizard.class.inc.php
Normal file
257
application/uiwizard.class.inc.php
Normal file
@@ -0,0 +1,257 @@
|
||||
<?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)
|
||||
{
|
||||
$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)
|
||||
{
|
||||
$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");
|
||||
$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>
|
||||
function OnEnterStep{$iStepIndex}()
|
||||
{
|
||||
oWizardHelper.ResetQuery();
|
||||
|
||||
$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)
|
||||
{
|
||||
$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("<form method=\"post\" action=\"../pages/UI.php\">\n");
|
||||
$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>\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("<input type=\"submit\" value=\"Create {$this->m_sClass}\">\n");
|
||||
$this->m_oPage->add("</form>\n");
|
||||
$this->m_oPage->add("</div>\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);
|
||||
|
||||
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)
|
||||
{
|
||||
$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;
|
||||
}
|
||||
}
|
||||
?>
|
||||
80
application/utils.inc.php
Normal file
80
application/utils.inc.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
define('CONFIGFILE', '../config.txt');
|
||||
|
||||
class utils
|
||||
{
|
||||
private static $m_aConfig = 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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public static function ReadConfig()
|
||||
{
|
||||
self::$m_aConfig = array();
|
||||
|
||||
$sConfigContents = self::ReadFromFile(CONFIGFILE);
|
||||
if (!$sConfigContents) throw new Exception("Could not load file ".CONFIGFILE);
|
||||
|
||||
foreach (explode("\n", $sConfigContents) as $sLine)
|
||||
{
|
||||
$sLine = trim($sLine);
|
||||
if (($iPos = strpos($sLine, '#')) !== false)
|
||||
{
|
||||
// strip out the end of the line right after the #
|
||||
$sLine = substr($sLine, 0, $iPos);
|
||||
}
|
||||
|
||||
$aMatches = array();
|
||||
if (preg_match("@(\\S+.*)=\s*(\S+.*)@", $sLine, $aMatches))
|
||||
{
|
||||
$sParamName = trim($aMatches[1]);
|
||||
$sParamValue = trim($aMatches[2]);
|
||||
self::$m_aConfig[$sParamName] = $sParamValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function GetConfig($sParamName, $defaultValue = "")
|
||||
{
|
||||
if (is_null(self::$m_aConfig))
|
||||
{
|
||||
self::ReadConfig();
|
||||
}
|
||||
|
||||
if (array_key_exists($sParamName, self::$m_aConfig))
|
||||
{
|
||||
return self::$m_aConfig[$sParamName];
|
||||
}
|
||||
else
|
||||
{
|
||||
return $defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
289
application/webpage.class.inc.php
Normal file
289
application/webpage.class.inc.php
Normal file
@@ -0,0 +1,289 @@
|
||||
<?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 web_page("Title of my page");
|
||||
* $oPage->p("Hello World !");
|
||||
* $oPage->output();
|
||||
*/
|
||||
class web_page
|
||||
{
|
||||
protected $s_title;
|
||||
protected $s_content;
|
||||
protected $a_scripts;
|
||||
protected $a_styles;
|
||||
protected $a_include_scripts;
|
||||
protected $a_include_stylesheets;
|
||||
protected $a_headers;
|
||||
|
||||
public function __construct($s_title)
|
||||
{
|
||||
$this->s_title = $s_title;
|
||||
$this->s_content = "";
|
||||
$this->a_scripts = array();
|
||||
$this->a_styles = array();
|
||||
$this->a_linked_scripts = array();
|
||||
$this->a_linked_stylesheets = array();
|
||||
$this->a_headers = array();
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add any text or HTML fragment to the body of the page
|
||||
*/
|
||||
public function add($s_html)
|
||||
{
|
||||
$this->s_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";
|
||||
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 "</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\">");
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
204
application/wizardhelper.class.inc.php
Normal file
204
application/wizardhelper.class.inc.php
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
require_once('../application/uiwizard.class.inc.php');
|
||||
|
||||
class WizardHelper
|
||||
{
|
||||
protected $m_aData;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function GetTargetObject()
|
||||
{
|
||||
$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->IsExternalKey()) && ($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;
|
||||
}
|
||||
|
||||
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 web_page
|
||||
{
|
||||
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())
|
||||
{
|
||||
}
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user