mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-26 21:54:13 +01:00
N°3912 - Polishing: Export - export of impact analysis
This commit is contained in:
@@ -10,6 +10,7 @@ use Combodo\iTop\Application\UI\Base\Component\Button\Button;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
|
||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\StaticTable\StaticTable;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Field\Field;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Field\FieldUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\FieldSet\FieldSet;
|
||||
@@ -1173,6 +1174,9 @@ HTML
|
||||
|
||||
public static function GetDisplaySetBlock(WebPage $oPage, DBObjectSet $oSet, $aExtraParams = array())
|
||||
{
|
||||
if ($oPage->IsPrintableVersion() || $oPage->is_pdf()) {
|
||||
return self::GetDisplaySetForPrinting($oPage, $oSet, $aExtraParams);
|
||||
}
|
||||
if (empty($aExtraParams['currentId'])) {
|
||||
$iListId = utils::GetUniqueId(); // Works only if not in an Ajax page !!
|
||||
} else {
|
||||
@@ -1181,6 +1185,146 @@ HTML
|
||||
|
||||
return DataTableUIBlockFactory::MakeForResult($oPage, $iListId, $oSet, $aExtraParams);
|
||||
}
|
||||
|
||||
public static function GetDataTableFromDBObjectSet(DBObjectSet $oSet, $aParams = array())
|
||||
{
|
||||
$aFields = null;
|
||||
if (isset($aParams['fields']) && (strlen($aParams['fields']) > 0)) {
|
||||
$aFields = explode(',', $aParams['fields']);
|
||||
}
|
||||
|
||||
$bFieldsAdvanced = false;
|
||||
if (isset($aParams['fields_advanced'])) {
|
||||
$bFieldsAdvanced = (bool)$aParams['fields_advanced'];
|
||||
}
|
||||
|
||||
$bLocalize = true;
|
||||
if (isset($aParams['localize_values'])) {
|
||||
$bLocalize = (bool)$aParams['localize_values'];
|
||||
}
|
||||
|
||||
$aList = array();
|
||||
|
||||
$aClasses = $oSet->GetFilter()->GetSelectedClasses();
|
||||
$aAuthorizedClasses = array();
|
||||
foreach ($aClasses as $sAlias => $sClassName) {
|
||||
if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $oSet) != UR_ALLOWED_NO) {
|
||||
$aAuthorizedClasses[$sAlias] = $sClassName;
|
||||
}
|
||||
}
|
||||
$aHeader = array();
|
||||
foreach ($aAuthorizedClasses as $sAlias => $sClassName) {
|
||||
$aList[$sAlias] = array();
|
||||
|
||||
foreach (MetaModel::GetZListItems($sClassName, 'list') as $sAttCode) {
|
||||
$oAttDef = Metamodel::GetAttributeDef($sClassName, $sAttCode);
|
||||
if (is_null($aFields) || (count($aFields) == 0)) {
|
||||
// Standard list of attributes (no link sets)
|
||||
if ($oAttDef->IsScalar() && ($oAttDef->IsWritable() || $oAttDef->IsExternalField())) {
|
||||
$sAttCodeEx = $oAttDef->IsExternalField() ? $oAttDef->GetKeyAttCode().'->'.$oAttDef->GetExtAttCode() : $sAttCode;
|
||||
|
||||
$aList[$sAlias][$sAttCodeEx] = $oAttDef;
|
||||
|
||||
if ($bFieldsAdvanced && $oAttDef->IsExternalKey(EXTKEY_RELATIVE)) {
|
||||
$sRemoteClass = $oAttDef->GetTargetClass();
|
||||
foreach (MetaModel::GetReconcKeys($sRemoteClass) as $sRemoteAttCode) {
|
||||
$aList[$sAlias][$sAttCode.'->'.$sRemoteAttCode] = MetaModel::GetAttributeDef($sRemoteClass,
|
||||
$sRemoteAttCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// User defined list of attributes
|
||||
if (in_array($sAttCode, $aFields) || in_array($sAlias.'.'.$sAttCode, $aFields)) {
|
||||
$aList[$sAlias][$sAttCode] = $oAttDef;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Replace external key by the corresponding friendly name (if not already in the list)
|
||||
foreach ($aList[$sAlias] as $sAttCode => $oAttDef) {
|
||||
if ($oAttDef->IsExternalKey()) {
|
||||
unset($aList[$sAlias][$sAttCode]);
|
||||
$sFriendlyNameAttCode = $sAttCode.'_friendlyname';
|
||||
if (!array_key_exists($sFriendlyNameAttCode,
|
||||
$aList[$sAlias]) && MetaModel::IsValidAttCode($sClassName, $sFriendlyNameAttCode)) {
|
||||
$oFriendlyNameAtt = MetaModel::GetAttributeDef($sClassName, $sFriendlyNameAttCode);
|
||||
$aList[$sAlias][$sFriendlyNameAttCode] = $oFriendlyNameAtt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($aList[$sAlias] as $sAttCodeEx => $oAttDef) {
|
||||
$sColLabel = $bLocalize ? MetaModel::GetLabel($sClassName, $sAttCodeEx) : $sAttCodeEx;
|
||||
|
||||
$oFinalAttDef = $oAttDef->GetFinalAttDef();
|
||||
if (get_class($oFinalAttDef) == 'AttributeDateTime') {
|
||||
$aHeader[$oAttDef->GetCode().'/D'] = ['label' => $sColLabel.' ('.Dict::S('UI:SplitDateTime-Date').')'];
|
||||
$aHeader[$oAttDef->GetCode().'/T'] = ['label' => $sColLabel.' ('.Dict::S('UI:SplitDateTime-Time').')'];
|
||||
} else {
|
||||
$aHeader[$oAttDef->GetCode()] = ['label' => $sColLabel];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$oSet->Seek(0);
|
||||
$aRows = [];
|
||||
while ($aObjects = $oSet->FetchAssoc()) {
|
||||
$aRow = [];
|
||||
foreach ($aAuthorizedClasses as $sAlias => $sClassName) {
|
||||
$oObj = $aObjects[$sAlias];
|
||||
foreach ($aList[$sAlias] as $sAttCodeEx => $oAttDef) {
|
||||
if (is_null($oObj)) {
|
||||
$aRow[$oAttDef->GetCode()] = '';
|
||||
} else {
|
||||
$oFinalAttDef = $oAttDef->GetFinalAttDef();
|
||||
if (get_class($oFinalAttDef) == 'AttributeDateTime') {
|
||||
$sDate = $oObj->Get($sAttCodeEx);
|
||||
if ($sDate === null) {
|
||||
$aRow[$oAttDef->GetCode().'/D'] = '';
|
||||
$aRow[$oAttDef->GetCode().'/T'] = '';
|
||||
} else {
|
||||
$iDate = AttributeDateTime::GetAsUnixSeconds($sDate);
|
||||
$aRow[$oAttDef->GetCode().'/D'] = date('Y-m-d', $iDate); // Format kept as-is for 100% backward compatibility of the exports
|
||||
$aRow[$oAttDef->GetCode().'/T'] = date('H:i:s', $iDate); // Format kept as-is for 100% backward compatibility of the exports
|
||||
}
|
||||
} else {
|
||||
if ($oAttDef instanceof AttributeCaseLog) {
|
||||
$rawValue = $oObj->Get($sAttCodeEx);
|
||||
$outputValue = str_replace("\n", "<br/>", htmlentities($rawValue->__toString(), ENT_QUOTES, 'UTF-8'));
|
||||
// Trick for Excel: treat the content as text even if it begins with an equal sign
|
||||
$aRow[$oAttDef->GetCode()] = $outputValue;
|
||||
} else {
|
||||
$rawValue = $oObj->Get($sAttCodeEx);
|
||||
// Due to custom formatting rules, empty friendlynames may be rendered as non-empty strings
|
||||
// let's fix this and make sure we render an empty string if the key == 0
|
||||
if ($oAttDef instanceof AttributeExternalField && $oAttDef->IsFriendlyName()) {
|
||||
$sKeyAttCode = $oAttDef->GetKeyAttCode();
|
||||
if ($oObj->Get($sKeyAttCode) == 0) {
|
||||
$rawValue = '';
|
||||
}
|
||||
}
|
||||
if ($bLocalize) {
|
||||
$outputValue = htmlentities($oFinalAttDef->GetEditValue($rawValue), ENT_QUOTES, 'UTF-8');
|
||||
} else {
|
||||
$outputValue = htmlentities($rawValue, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
$aRow[$oAttDef->GetCode()] = $outputValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$aRows[] = $aRow;
|
||||
}
|
||||
$oTable = new StaticTable();
|
||||
$oTable->SetColumns($aHeader);
|
||||
$oTable->SetData($aRows);
|
||||
|
||||
return $oTable;
|
||||
//DataTableUIBlockFactory::MakeForStaticData('', $aHeader, $aRows);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param \CMDBObjectSet $oSet
|
||||
|
||||
@@ -119,13 +119,12 @@ class DisplayableNode extends GraphNode
|
||||
$Alpha = 1.0;
|
||||
$oPdf->SetFillColor(200, 200, 200);
|
||||
$oPdf->setAlpha(1);
|
||||
|
||||
|
||||
$sIconUrl = $this->GetProperty('icon_url');
|
||||
$sIconPath = str_replace(utils::GetAbsoluteUrlModulesRoot(), APPROOT.'env-'.utils::GetCurrentEnvironment().'/', $sIconUrl);
|
||||
|
||||
if ($this->GetProperty('source'))
|
||||
{
|
||||
$oPdf->SetLineStyle(array('width' => 2*$fScale, 'cap' => 'round', 'join' => 'miter', 'dash' => 0, 'color' => array(204, 51, 51)));
|
||||
|
||||
if ($this->GetProperty('source')) {
|
||||
$oPdf->SetLineStyle(array('width' => 2 * $fScale, 'cap' => 'round', 'join' => 'miter', 'dash' => 0, 'color' => array(204, 51, 51)));
|
||||
$oPdf->Circle($this->x * $fScale, $this->y * $fScale, 16 * 1.25 * $fScale, 0, 360, 'D');
|
||||
}
|
||||
else if ($this->GetProperty('sink'))
|
||||
@@ -133,34 +132,30 @@ class DisplayableNode extends GraphNode
|
||||
$oPdf->SetLineStyle(array('width' => 2*$fScale, 'cap' => 'round', 'join' => 'miter', 'dash' => 0, 'color' => array(51, 51, 204)));
|
||||
$oPdf->Circle($this->x * $fScale, $this->y * $fScale, 16 * 1.25 * $fScale, 0, 360, 'D');
|
||||
}
|
||||
|
||||
if (!$this->GetProperty('is_reached'))
|
||||
{
|
||||
|
||||
if (!$this->GetProperty('is_reached')) {
|
||||
$sTempImageName = $this->CreateWhiteIcon($oGraph, $sIconPath);
|
||||
if ($sTempImageName != null)
|
||||
{
|
||||
$oPdf->Image($sTempImageName, ($this->x - 16)*$fScale, ($this->y - 16)*$fScale, 32*$fScale, 32*$fScale, 'PNG');
|
||||
if ($sTempImageName != null) {
|
||||
$oPdf->AddImage($sTempImageName, ($this->x - 16) * $fScale, ($this->y - 16) * $fScale, 32 * $fScale, 32 * $fScale, 'PNG');
|
||||
}
|
||||
$Alpha = 0.4;
|
||||
$oPdf->setAlpha($Alpha);
|
||||
}
|
||||
|
||||
$oPdf->Image($sIconPath, ($this->x - 16)*$fScale, ($this->y - 16)*$fScale, 32*$fScale, 32*$fScale);
|
||||
|
||||
|
||||
$oPdf->AddImage($sIconPath, ($this->x - 16) * $fScale, ($this->y - 16) * $fScale, 32 * $fScale, 32 * $fScale);
|
||||
|
||||
$aContextRootCauses = $this->GetProperty('context_root_causes');
|
||||
if (!is_null($aContextRootCauses))
|
||||
{
|
||||
if (!is_null($aContextRootCauses)) {
|
||||
$idx = 0;
|
||||
foreach($aContextRootCauses as $key => $aObjects)
|
||||
{
|
||||
$sgn = 2*($idx %2) -1;
|
||||
$coef = floor((1+$idx)/2) * $sgn;
|
||||
$alpha = $coef*pi()/4 - pi()/2;
|
||||
$x = $this->x * $fScale + cos($alpha) * 16*1.25 * $fScale;
|
||||
$y = $this->y * $fScale + sin($alpha) * 16*1.25 * $fScale;
|
||||
foreach ($aContextRootCauses as $key => $aObjects) {
|
||||
$sgn = 2 * ($idx % 2) - 1;
|
||||
$coef = floor((1 + $idx) / 2) * $sgn;
|
||||
$alpha = $coef * pi() / 4 - pi() / 2;
|
||||
$x = $this->x * $fScale + cos($alpha) * 16 * 1.25 * $fScale;
|
||||
$y = $this->y * $fScale + sin($alpha) * 16 * 1.25 * $fScale;
|
||||
$l = 32 * $fScale / 3;
|
||||
$sIconPath = APPROOT.'env-'.utils::GetCurrentEnvironment().'/'.$aContextDefs[$key]['icon'];
|
||||
$oPdf->Image($sIconPath, $x - $l/2, $y - $l/2, $l, $l);
|
||||
$oPdf->AddImage($sIconPath, $x - $l / 2, $y - $l / 2, $l, $l);
|
||||
$idx++;
|
||||
}
|
||||
}
|
||||
@@ -779,8 +774,8 @@ class DisplayableGroupNode extends DisplayableNode
|
||||
{
|
||||
$aBorderColor = array(200, 200, 200);
|
||||
}
|
||||
$oPdf->SetLineStyle(array('width' => 2*$fScale, 'cap' => 'round', 'join' => 'miter', 'dash' => 0, 'color' => $aBorderColor));
|
||||
|
||||
$oPdf->SetLineStyle(array('width' => 2 * $fScale, 'cap' => 'round', 'join' => 'miter', 'dash' => 0, 'color' => $aBorderColor));
|
||||
|
||||
$sIconUrl = $this->GetProperty('icon_url');
|
||||
$sIconPath = str_replace(utils::GetAbsoluteUrlModulesRoot(), APPROOT.'env-'.utils::GetCurrentEnvironment().'/', $sIconUrl);
|
||||
$oPdf->SetAlpha(1);
|
||||
@@ -794,13 +789,13 @@ class DisplayableGroupNode extends DisplayableNode
|
||||
{
|
||||
$oPdf->SetAlpha(0.4);
|
||||
}
|
||||
$oPdf->Image($sIconPath, ($this->x - 17)*$fScale, ($this->y - 17)*$fScale, 16*$fScale, 16*$fScale);
|
||||
$oPdf->Image($sIconPath, ($this->x + 1)*$fScale, ($this->y - 17)*$fScale, 16*$fScale, 16*$fScale);
|
||||
$oPdf->Image($sIconPath, ($this->x -8)*$fScale, ($this->y +1)*$fScale, 16*$fScale, 16*$fScale);
|
||||
$oPdf->AddImage($sIconPath, ($this->x - 17) * $fScale, ($this->y - 17) * $fScale, 16 * $fScale, 16 * $fScale);
|
||||
$oPdf->AddImage($sIconPath, ($this->x + 1) * $fScale, ($this->y - 17) * $fScale, 16 * $fScale, 16 * $fScale);
|
||||
$oPdf->AddImage($sIconPath, ($this->x - 8) * $fScale, ($this->y + 1) * $fScale, 16 * $fScale, 16 * $fScale);
|
||||
$oPdf->SetFontParams('', 24 * $fScale, '', true);
|
||||
$width = $oPdf->GetStringWidth($this->GetProperty('label'));
|
||||
$oPdf->SetTextColor(0, 0, 0);
|
||||
$oPdf->Text($this->x*$fScale - $width/2, ($this->y + 25)*$fScale, $this->GetProperty('label'));
|
||||
$oPdf->Text($this->x * $fScale - $width / 2, ($this->y + 25) * $fScale, $this->GetProperty('label'));
|
||||
}
|
||||
|
||||
public function GetTooltip($aContextDefs)
|
||||
@@ -1185,7 +1180,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
|
||||
return json_encode($aData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sort class "codes" based on their localized name
|
||||
* @param string $sClass1
|
||||
@@ -1196,12 +1191,12 @@ class DisplayableGraph extends SimpleGraph
|
||||
{
|
||||
return strcasecmp(MetaModel::GetName($sClass1), MetaModel::GetName($sClass2));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Renders the graph in a PDF document: centered in the current page
|
||||
* @param PDFPage $oPage The PDFPage representing the PDF document to draw into
|
||||
* @param string $sComments An optional comment to display next to the graph (HTML entities will be escaped, \n replaced by <br/>)
|
||||
* @param string $sContextKey The key to fetch the queries in the configuration. Example: itop-tickets/relation_context/UserRequest/impacts/down
|
||||
* @param string $sContextKey The key to fetch the queries in the configuration. Example: itop-tickets/relation_context/UserRequest/impacts/down
|
||||
* @param float $xMin Left coordinate of the bounding box to display the graph
|
||||
* @param float $xMax Right coordinate of the bounding box to display the graph
|
||||
* @param float $yMin Top coordinate of the bounding box to display the graph
|
||||
@@ -1329,20 +1324,18 @@ class DisplayableGraph extends SimpleGraph
|
||||
$yPos = $yMin + $fPadding;
|
||||
$oPdf->SetFillColor(225, 225, 225);
|
||||
$oPdf->Cell($fIconSize + $fPadding + $fMaxWidth, $fIconSize + $fPadding, Dict::S('UI:Relation:Key'), 0 /* border */, 1 /* ln */, 'C', true /* fill */);
|
||||
$yPos += $fIconSize + 2*$fPadding;
|
||||
foreach($aClasses as $sClass => $sLabel)
|
||||
{
|
||||
$yPos += $fIconSize + 2 * $fPadding;
|
||||
foreach ($aClasses as $sClass => $sLabel) {
|
||||
$oPdf->SetX($xMin + $fIconSize + $fPadding);
|
||||
$oPdf->Cell(0, $fIconSize + 2*$fPadding, $sLabel, 0 /* border */, 1 /* ln */);
|
||||
$oPdf->Image($aIcons[$sClass], $xMin+1, $yPos, $fIconSize, $fIconSize);
|
||||
$yPos += $fIconSize + 2*$fPadding;
|
||||
$oPdf->Cell(0, $fIconSize + 2 * $fPadding, $sLabel, 0 /* border */, 1 /* ln */);
|
||||
$oPdf->AddImage($aIcons[$sClass], $xMin + 1, $yPos, $fIconSize, $fIconSize);
|
||||
$yPos += $fIconSize + 2 * $fPadding;
|
||||
}
|
||||
foreach($aContexts as $key => $sLabel)
|
||||
{
|
||||
foreach ($aContexts as $key => $sLabel) {
|
||||
$oPdf->SetX($xMin + $fIconSize + $fPadding);
|
||||
$oPdf->Cell(0, $fIconSize + 2*$fPadding, $sLabel, 0 /* border */, 1 /* ln */);
|
||||
$oPdf->Image($aContextIcons[$key], $xMin+1+$fIconSize*0.125, $yPos+$fIconSize*0.125, $fIconSize*0.75, $fIconSize*0.75);
|
||||
$yPos += $fIconSize + 2*$fPadding;
|
||||
$oPdf->Cell(0, $fIconSize + 2 * $fPadding, $sLabel, 0 /* border */, 1 /* ln */);
|
||||
$oPdf->AddImage($aContextIcons[$key], $xMin + 1 + $fIconSize * 0.125, $yPos + $fIconSize * 0.125, $fIconSize * 0.75, $fIconSize * 0.75);
|
||||
$yPos += $fIconSize + 2 * $fPadding;
|
||||
}
|
||||
$oPdf->Rect($xMin, $yMin, $fMaxWidth + $fIconSize + 3*$fPadding, $yMax - $yMin, 'D');
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
|
||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Title\TitleUIBlockFactory;
|
||||
use Combodo\iTop\Controller\AjaxRenderController;
|
||||
use Combodo\iTop\Controller\Base\Layout\ActivityPanelController;
|
||||
use Combodo\iTop\Controller\PreferencesController;
|
||||
@@ -2002,63 +2005,51 @@ EOF
|
||||
$aContexts = utils::ReadParam('contexts', array(), false, 'raw_data');
|
||||
$sContextKey = utils::ReadParam('context_key', '', false, 'raw_data');
|
||||
$aPositions = null;
|
||||
if ($sPositions != null)
|
||||
{
|
||||
if ($sPositions != null) {
|
||||
$aPositions = json_decode($sPositions, true);
|
||||
}
|
||||
|
||||
// Get the list of source objects
|
||||
$aSources = utils::ReadParam('sources', array(), false, 'raw_data');
|
||||
$aSourceObjects = array();
|
||||
foreach($aSources as $sClass => $aIDs)
|
||||
{
|
||||
foreach ($aSources as $sClass => $aIDs) {
|
||||
$oSearch = new DBObjectSearch($sClass);
|
||||
$oSearch->AddCondition('id', $aIDs, 'IN');
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
while ($oObj = $oSet->Fetch())
|
||||
{
|
||||
while ($oObj = $oSet->Fetch()) {
|
||||
$aSourceObjects[] = $oObj;
|
||||
}
|
||||
}
|
||||
$sSourceClass = '*';
|
||||
if (count($aSourceObjects) == 1)
|
||||
{
|
||||
if (count($aSourceObjects) == 1) {
|
||||
$sSourceClass = get_class($aSourceObjects[0]);
|
||||
}
|
||||
|
||||
// Get the list of excluded objects
|
||||
$aExcluded = utils::ReadParam('excluded', array(), false, 'raw_data');
|
||||
$aExcludedObjects = array();
|
||||
foreach($aExcluded as $sClass => $aIDs)
|
||||
{
|
||||
foreach ($aExcluded as $sClass => $aIDs) {
|
||||
$oSearch = new DBObjectSearch($sClass);
|
||||
$oSearch->AddCondition('id', $aIDs, 'IN');
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
while ($oObj = $oSet->Fetch())
|
||||
{
|
||||
while ($oObj = $oSet->Fetch()) {
|
||||
$aExcludedObjects[] = $oObj;
|
||||
}
|
||||
}
|
||||
|
||||
$iMaxRecursionDepth = MetaModel::GetConfig()->Get('relations_max_depth');
|
||||
if ($sDirection == 'up')
|
||||
{
|
||||
if ($sDirection == 'up') {
|
||||
$oRelGraph = MetaModel::GetRelatedObjectsUp($sRelation, $aSourceObjects, $iMaxRecursionDepth, true, $aContexts);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oRelGraph = MetaModel::GetRelatedObjectsDown($sRelation, $aSourceObjects, $iMaxRecursionDepth, true, $aExcludedObjects, $aContexts);
|
||||
}
|
||||
|
||||
// Remove excluded classes from the graph
|
||||
if (count($aExcludedClasses) > 0)
|
||||
{
|
||||
if (count($aExcludedClasses) > 0) {
|
||||
$oIterator = new RelationTypeIterator($oRelGraph, 'Node');
|
||||
foreach($oIterator as $oNode)
|
||||
{
|
||||
foreach ($oIterator as $oNode) {
|
||||
$oObj = $oNode->GetProperty('object');
|
||||
if ($oObj && in_array(get_class($oObj), $aExcludedClasses))
|
||||
{
|
||||
if ($oObj && in_array(get_class($oObj), $aExcludedClasses)) {
|
||||
$oRelGraph->FilterNode($oNode);
|
||||
}
|
||||
}
|
||||
@@ -2069,36 +2060,29 @@ EOF
|
||||
|
||||
$oGraph = DisplayableGraph::FromRelationGraph($oRelGraph, $iGroupingThreshold, ($sDirection == 'down'));
|
||||
$oGraph->InitFromGraphviz();
|
||||
if ($aPositions != null)
|
||||
{
|
||||
if ($aPositions != null) {
|
||||
$oGraph->UpdatePositions($aPositions);
|
||||
}
|
||||
|
||||
$aGroups = array();
|
||||
$oIterator = new RelationTypeIterator($oGraph, 'Node');
|
||||
foreach($oIterator as $oNode)
|
||||
{
|
||||
if ($oNode instanceof DisplayableGroupNode)
|
||||
{
|
||||
foreach ($oIterator as $oNode) {
|
||||
if ($oNode instanceof DisplayableGroupNode) {
|
||||
$aGroups[$oNode->GetProperty('group_index')] = $oNode->GetObjects();
|
||||
}
|
||||
}
|
||||
// First page is the graph
|
||||
$oGraph->RenderAsPDF($oPage, $sComments, $sContextKey);
|
||||
|
||||
if ($bIncludeList)
|
||||
{
|
||||
if ($bIncludeList) {
|
||||
// Then the lists of objects (one table per finalclass)
|
||||
$aResults = array();
|
||||
$oIterator = new RelationTypeIterator($oRelGraph, 'Node');
|
||||
foreach($oIterator as $oNode)
|
||||
{
|
||||
foreach ($oIterator as $oNode) {
|
||||
$oObj = $oNode->GetProperty('object'); // Some nodes (Redundancy Nodes and Group) do not contain an object
|
||||
if ($oObj)
|
||||
{
|
||||
if ($oObj) {
|
||||
$sObjClass = get_class($oObj);
|
||||
if (!array_key_exists($sObjClass, $aResults))
|
||||
{
|
||||
if (!array_key_exists($sObjClass, $aResults)) {
|
||||
$aResults[$sObjClass] = array();
|
||||
}
|
||||
$aResults[$sObjClass][] = $oObj;
|
||||
@@ -2107,49 +2091,43 @@ EOF
|
||||
|
||||
$oPage->get_tcpdf()->AddPage();
|
||||
$oPage->get_tcpdf()->SetFontSize(10); // Reset the font size to its default
|
||||
$oPage->add('<div class="page_header"><h1>'.Dict::S('UI:RelationshipList').'</h1></div>');
|
||||
$oPage->AddSubBlock(TitleUIBlockFactory::MakeNeutral(Dict::S('UI:RelationshipList')));
|
||||
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
|
||||
foreach($aResults as $sListClass => $aObjects)
|
||||
{
|
||||
foreach ($aResults as $sListClass => $aObjects) {
|
||||
set_time_limit($iLoopTimeLimit * count($aObjects));
|
||||
$oSet = CMDBObjectSet::FromArray($sListClass, $aObjects);
|
||||
$oSet->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||
$sHtml = "<div class=\"page_header\">\n";
|
||||
$sHtml .= "<table class=\"section\"><tr><td>".MetaModel::GetClassIcon($sListClass, true, 'width: 24px; height: 24px;')." ".Dict::Format('UI:Search:Count_ObjectsOf_Class_Found', $oSet->Count(),
|
||||
Metamodel::GetName($sListClass))."</td></tr></table>\n";
|
||||
$sHtml .= "</div>\n";
|
||||
$oPage->add($sHtml);
|
||||
cmdbAbstractObject::DisplaySet($oPage, $oSet, array('table_id' => $sSourceClass.'_'.$sRelation.'_'.$sDirection.'_'.$sListClass));
|
||||
$oPage->p(''); // Some space
|
||||
$sIconUrl = MetaModel::GetClassIcon($sListClass, false);
|
||||
$sIconUrl = str_replace(utils::GetAbsoluteUrlModulesRoot(), APPROOT.'env-'.utils::GetCurrentEnvironment().'/', $sIconUrl);
|
||||
$oTitle = new Html("<img src=\"$sIconUrl\" style=\"vertical-align:middle;width: 24px; height: 24px;\"/> ".Dict::Format('UI:Search:Count_ObjectsOf_Class_Found', $oSet->Count(), Metamodel::GetName($sListClass)));
|
||||
$oPage->AddSubBlock(TitleUIBlockFactory::MakeStandard($oTitle, 2));
|
||||
$oPage->AddSubBlock(cmdbAbstractObject::GetDataTableFromDBObjectSet($oSet, array('table_id' => $sSourceClass.'_'.$sRelation.'_'.$sDirection.'_'.$sListClass)));
|
||||
}
|
||||
|
||||
// Then the content of the groups (one table per group)
|
||||
if (count($aGroups) > 0)
|
||||
{
|
||||
if (count($aGroups) > 0) {
|
||||
$oPage->get_tcpdf()->AddPage();
|
||||
$oPage->add('<div class="page_header"><h1>'.Dict::S('UI:RelationGroups').'</h1></div>');
|
||||
foreach($aGroups as $idx => $aObjects)
|
||||
{
|
||||
$oPage->AddSubBlock(TitleUIBlockFactory::MakeNeutral(Dict::S('UI:RelationGroups')));
|
||||
foreach ($aGroups as $idx => $aObjects) {
|
||||
set_time_limit($iLoopTimeLimit * count($aObjects));
|
||||
$sListClass = get_class(current($aObjects));
|
||||
$oSet = CMDBObjectSet::FromArray($sListClass, $aObjects);
|
||||
$sHtml = "<div class=\"page_header\">\n";
|
||||
$sHtml .= "<table class=\"section\"><tr><td>".MetaModel::GetClassIcon($sListClass, true, 'width: 24px; height: 24px;')." ".Dict::Format('UI:RelationGroupNumber_N', (1 + $idx))."</td></tr></table>\n";
|
||||
$sHtml .= "</div>\n";
|
||||
$oPage->add($sHtml);
|
||||
cmdbAbstractObject::DisplaySet($oPage, $oSet);
|
||||
$oPage->p(''); // Some space
|
||||
$sIconUrl = MetaModel::GetClassIcon($sListClass, false);
|
||||
$sIconUrl = str_replace(utils::GetAbsoluteUrlModulesRoot(), APPROOT.'env-'.utils::GetCurrentEnvironment().'/', $sIconUrl);
|
||||
$oTitle = new Html("<img src=\"$sIconUrl\" style=\"vertical-align:middle;width: 24px; height: 24px;\"/> ".Dict::Format('UI:RelationGroupNumber_N', (1 + $idx)), Metamodel::GetName($sListClass));
|
||||
$oPage->AddSubBlock(TitleUIBlockFactory::MakeStandard($oTitle, 2));
|
||||
$oPage->AddSubBlock(cmdbAbstractObject::GetDataTableFromDBObjectSet($oSet));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($operation == 'relation_attachment')
|
||||
{
|
||||
if ($operation == 'relation_attachment') {
|
||||
$sObjClass = utils::ReadParam('obj_class', '', false, 'class');
|
||||
$iObjKey = (int)utils::ReadParam('obj_key', 0, false, 'integer');
|
||||
|
||||
// Save the generated PDF as an attachment
|
||||
$sPDF = $oPage->get_pdf();
|
||||
$oPage = new ajax_page('');
|
||||
$oPage = new AjaxPage('');
|
||||
$oAttachment = MetaModel::NewObject('Attachment');
|
||||
$oAttachment->Set('item_class', $sObjClass);
|
||||
$oAttachment->Set('item_id', $iObjKey);
|
||||
|
||||
@@ -67,10 +67,10 @@ class PDFPage extends WebPage
|
||||
table {
|
||||
padding: 2pt;
|
||||
}
|
||||
table.listResults td {
|
||||
table.ibo-datatable td {
|
||||
border: 0.5pt solid #000 ;
|
||||
}
|
||||
table.listResults th {
|
||||
table.ibo-datatable th {
|
||||
background-color: #eee;
|
||||
border: 0.5pt solid #000 ;
|
||||
}
|
||||
@@ -86,6 +86,13 @@ table.section td {
|
||||
td.icon {
|
||||
width: 30px;
|
||||
}
|
||||
h2{
|
||||
font-size: 10pt;
|
||||
vertical-align: middle;
|
||||
background-color:#eee;
|
||||
padding: 2pt;
|
||||
margin:2pt;
|
||||
}
|
||||
EOF
|
||||
);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,32 @@ class iTopPDF extends TCPDF
|
||||
$this->sDocumentTitle = $sDocumentTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add image
|
||||
*
|
||||
* @param string $sImagePath Name of the SVG file or a '@' character followed by the SVG data string.
|
||||
* @param $x (float) Abscissa of the upper-left corner.
|
||||
* @param $y (float) Ordinate of the upper-left corner.
|
||||
* @param $w (float) Width of the image in the page. If not specified or equal to zero, it is automatically calculated.
|
||||
* @param $h (float) Height of the image in the page. If not specified or equal to zero, it is automatically calculated.
|
||||
*/
|
||||
public function AddImage($sImagePath, $x = '', $y = '', $w = 0, $h = 0)
|
||||
{
|
||||
/*if (endsWith(strtolower($sImagePath), ".svg")) {
|
||||
$this->ImageSVG($sImagePath, $x, $y, $w, $h);
|
||||
} else {
|
||||
$this->Image($sImagePath, $x, $y, $w, $h);
|
||||
}*/
|
||||
$imgtype = TCPDF_IMAGES::getImageFileType($sImagePath);
|
||||
if (($imgtype == 'eps') or ($imgtype == 'ai')) {
|
||||
$this->ImageEps($sImagePath, $x, $y, $w, $h);;
|
||||
} elseif ($imgtype == 'svg') {
|
||||
$this->ImageSVG($sImagePath, $x, $y, $w, $h);;
|
||||
} else {
|
||||
$this->Image($sImagePath, $x, $y, $w, $h);;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the custom header. Called for each new page.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user