mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01:00
More options for the PDF export of the 'impact' graph.
SVN:trunk[3577]
This commit is contained in:
@@ -705,7 +705,45 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
|
||||
public static function DisplaySet(WebPage $oPage, CMDBObjectSet $oSet, $aExtraParams = array())
|
||||
{
|
||||
$oPage->add(self::GetDisplaySet($oPage, $oSet, $aExtraParams));
|
||||
if ($oPage->is_pdf())
|
||||
{
|
||||
$oPage->add(self::DisplaySetForPrinting($oPage, $oSet, $aExtraParams));
|
||||
}
|
||||
else
|
||||
{
|
||||
$oPage->add(self::GetDisplaySet($oPage, $oSet, $aExtraParams));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplifed version of GetDisplaySet() with less "decoration" around the table (and no paging)
|
||||
* that fits better into a printed document (like a PDF)
|
||||
* @param PDFPage $oPage
|
||||
* @param DBObjectSet $oSet
|
||||
* @param hash $aExtraParams
|
||||
* @return string The HTML representation of the table
|
||||
*/
|
||||
public static function DisplaySetForPrinting(PDFPage $oPage, DBObjectSet $oSet, $aExtraParams = array())
|
||||
{
|
||||
$iListId = empty($aExtraParams['currentId']) ? $oPage->GetUniqueId() : $aExtraParams['currentId'];
|
||||
$sTableId = isset($aExtraParams['table_id']) ? $aExtraParams['table_id'] : null;
|
||||
|
||||
$bViewLink = true;
|
||||
$sSelectMode = 'none';
|
||||
$iListId = $sTableId;
|
||||
$sClassAlias = $oSet->GetClassAlias();
|
||||
$sClassName = $oSet->GetClass();
|
||||
$sZListName = 'list';
|
||||
$aClassAliases = array( $sClassAlias => $sClassName);
|
||||
$aList = cmdbAbstractObject::FlattenZList(MetaModel::GetZListItems($sClassName, $sZListName));
|
||||
|
||||
$oDataTable = new PrintableDataTable($iListId, $oSet, $aClassAliases, $sTableId);
|
||||
$oSettings = DataTableSettings::GetDataModelSettings($aClassAliases, $bViewLink, array($sClassAlias => $aList));
|
||||
$oSettings->iDefaultPageSize = 0;
|
||||
$oSettings->aSortOrder = MetaModel::GetOrderByDefault($sClassName);
|
||||
|
||||
return $oDataTable->Display($oPage, $oSettings, false /* $bDisplayMenu */, $sSelectMode, $bViewLink, $aExtraParams);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -606,6 +606,34 @@ EOF
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplified version of the data table with less "decoration" (and no paging)
|
||||
* which is optimized for printing
|
||||
*/
|
||||
class PrintableDataTable extends DataTable
|
||||
{
|
||||
public function GetAsHTML(WebPage $oPage, $iPageSize, $iDefaultPageSize, $iPageIndex, $aColumns, $bActionsMenu, $bToolkitMenu, $sSelectMode, $bViewLink, $aExtraParams)
|
||||
{
|
||||
return $this->GetHTMLTable($oPage, $aColumns, $sSelectMode, -1, $bViewLink, $aExtraParams);
|
||||
}
|
||||
|
||||
public function GetHTMLTable(WebPage $oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
|
||||
{
|
||||
$iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize);
|
||||
if ($iPageSize < 1)
|
||||
{
|
||||
$iPageSize = -1; // convention: no pagination
|
||||
}
|
||||
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
||||
|
||||
$aValues = $this->GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
||||
|
||||
$sHtml = $oPage->GetTable($aAttribs, $aValues);
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
}
|
||||
|
||||
class DataTableSettings implements Serializable
|
||||
{
|
||||
public $aClassAliases;
|
||||
|
||||
190
application/pdfpage.class.inc.php
Normal file
190
application/pdfpage.class.inc.php
Normal file
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
require_once(APPROOT.'lib/tcpdf/tcpdf.php');
|
||||
|
||||
/**
|
||||
* Custom class derived from TCPDF for providing custom headers and footers
|
||||
* @author denis
|
||||
*
|
||||
*/
|
||||
class iTopPDF extends TCPDF
|
||||
{
|
||||
protected $sDocumentTitle;
|
||||
|
||||
public function SetDocumentTitle($sDocumentTitle)
|
||||
{
|
||||
$this->sDocumentTitle = $sDocumentTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the custom header. Called for each new page.
|
||||
* @see TCPDF::Header()
|
||||
*/
|
||||
public function Header()
|
||||
{
|
||||
// Title
|
||||
// Set font
|
||||
$this->SetFont('dejavusans', 'B', 10);
|
||||
|
||||
$iPageNumberWidth = 25;
|
||||
$aMargins = $this->getMargins();
|
||||
|
||||
// Display the title (centered)
|
||||
$this->SetY(0);
|
||||
$this->MultiCell($this->getPageWidth() - $aMargins['left'] - $aMargins['right'] - $iPageNumberWidth, 15, $this->sDocumentTitle, 0, 'C', false, 0 /* $ln */, '', '', true, 0, false, true, 15, 'M' /* $valign */);
|
||||
$this->SetFont('dejavusans', '', 10);
|
||||
|
||||
// Display the page number (right aligned)
|
||||
// Warning: the 'R'ight alignment does not work when using placeholders like $this->getAliasNumPage() or $this->getAliasNbPages()
|
||||
$this->MultiCell($iPageNumberWidth, 15, 'Page '.$this->page, 0, 'R', false, 0 /* $ln */, '', '', true, 0, false, true, 15, 'M' /* $valign */);
|
||||
|
||||
// Branding logo
|
||||
$sBrandingIcon = APPROOT.'images/itop-logo.png';
|
||||
if (file_exists(MODULESROOT.'branding/main-logo.png'))
|
||||
{
|
||||
$sBrandingIcon = MODULESROOT.'branding/main-logo.png';
|
||||
}
|
||||
$this->Image($sBrandingIcon, $aMargins['left'], 5, 0, 10);
|
||||
}
|
||||
|
||||
// Page footer
|
||||
public function Footer()
|
||||
{
|
||||
// No footer
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Special class of WebPage for printing into a PDF document
|
||||
*/
|
||||
class PDFPage extends WebPage
|
||||
{
|
||||
/**
|
||||
* Instance of the TCPDF object for creating the PDF
|
||||
* @var TCPDF
|
||||
*/
|
||||
protected $oPdf;
|
||||
|
||||
public function __construct($s_title, $sPageFormat = 'A4', $sPageOrientation = 'L')
|
||||
{
|
||||
parent::__construct($s_title);
|
||||
define(K_PATH_FONTS, APPROOT.'lib/tcpdf/fonts');
|
||||
$this->oPdf = new iTopPDF($sPageOrientation, 'mm', $sPageFormat, true, 'UTF-8', false);
|
||||
|
||||
// set document information
|
||||
$this->oPdf->SetCreator(PDF_CREATOR);
|
||||
$this->oPdf->SetAuthor('iTop');
|
||||
$this->oPdf->SetTitle($s_title);
|
||||
$this->oPdf->SetDocumentTitle($s_title);
|
||||
|
||||
$this->oPdf->setFontSubsetting(true);
|
||||
|
||||
// Set font
|
||||
// dejavusans is a UTF-8 Unicode font. Standard PDF fonts like helvetica or times new roman are NOT UTF-8
|
||||
$this->oPdf->SetFont('dejavusans', '', 10, '', true);
|
||||
|
||||
// set auto page breaks
|
||||
$this->oPdf->SetAutoPageBreak(true, 15); // 15 mm break margin at the bottom
|
||||
$this->oPdf->SetTopMargin(15);
|
||||
|
||||
// Add a page, we're ready to start
|
||||
$this->oPdf->AddPage();
|
||||
|
||||
$this->SetContentType('application/pdf');
|
||||
$this->SetContentDisposition('inline', $s_title.'.pdf');
|
||||
$this->SetDefaultStyle();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a default style (suitable for printing) to be included each time $this->oPdf->writeHTML() is called
|
||||
*/
|
||||
protected function SetDefaultStyle()
|
||||
{
|
||||
$this->add_style(
|
||||
<<<EOF
|
||||
table.listResults td {
|
||||
border: 0.5pt solid #000 ;
|
||||
padding: 0.5pt;
|
||||
}
|
||||
table.listResults th {
|
||||
background-color: #eee;
|
||||
border: 0.5pt solid #000 ;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #000;
|
||||
}
|
||||
table.section td {
|
||||
vertical-align: middle;
|
||||
font-size: 10pt;
|
||||
background-color:#eee;
|
||||
}
|
||||
td.icon {
|
||||
width: 30px;
|
||||
}
|
||||
EOF
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access to the underlying TCPDF object
|
||||
* @return TCPDF
|
||||
*/
|
||||
public function get_tcpdf()
|
||||
{
|
||||
$this->flush();
|
||||
return $this->oPdf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the currently buffered HTML content into the PDF. This can be useful:
|
||||
* - to sync the flow in case you want to access the underlying TCPDF object for some specific/graphic output
|
||||
* - to process the HTML by smaller chunks instead of processing the whole page at once for performance reasons
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
if (strlen($this->s_content) > 0)
|
||||
{
|
||||
$sHtml = '';
|
||||
if (count($this->a_styles) > 0)
|
||||
{
|
||||
$sHtml .= "<style>\n".implode("\n", $this->a_styles)."\n</style>\n";
|
||||
}
|
||||
$sHtml .= $this->s_content;
|
||||
$this->oPdf->writeHTML($sHtml); // The style(s) must be supplied each time we call writeHtml
|
||||
$this->s_content = '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the page is a PDF page
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_pdf()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the PDF document and returns the PDF content as a string
|
||||
* @return string
|
||||
* @see WebPage::output()
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
if (!empty($this->sContentType))
|
||||
{
|
||||
$this->add_header('Content-type: '.$this->sContentType);
|
||||
}
|
||||
if (!empty($this->sContentDisposition))
|
||||
{
|
||||
$this->add_header('Content-Disposition: '.$this->sContentDisposition.'; filename="'.$this->sContentFileName.'"');
|
||||
}
|
||||
foreach($this->a_headers as $s_header)
|
||||
{
|
||||
header($s_header);
|
||||
}
|
||||
$this->flush();
|
||||
echo $this->oPdf->Output($this->s_title.'.pdf', 'S');
|
||||
}
|
||||
}
|
||||
@@ -268,7 +268,27 @@ class WebPage implements Page
|
||||
{
|
||||
$this->a_linked_stylesheets[] = array( 'link' => $s_linked_stylesheet, 'condition' => $s_condition);
|
||||
}
|
||||
|
||||
|
||||
public function add_saas($sSaasRelPath)
|
||||
{
|
||||
$sSaasPath = APPROOT.$sSaasRelPath;
|
||||
$sCssRelPath = preg_replace('/\.scss$/', '.css', $sSaasRelPath);
|
||||
$sCssPath = APPROOT.$sCssRelPath;
|
||||
clearstatcache();
|
||||
if (!file_exists($sCssPath) || (is_writable($sCssPath) && (filemtime($sCssPath) < filemtime($sSaasPath))))
|
||||
{
|
||||
// Rebuild the CSS file from the Saas file
|
||||
if (file_exists(APPROOT.'lib/sass/sass/SassParser.php'))
|
||||
{
|
||||
require_once(APPROOT.'lib/sass/sass/SassParser.php'); //including Sass libary (Syntactically Awesome Stylesheets)
|
||||
$oParser = new SassParser(array('style'=>'expanded'));
|
||||
$sCss = $oParser->toCss($sSaasPath);
|
||||
file_put_contents($sCssPath, $sCss);
|
||||
}
|
||||
}
|
||||
$sCSSUrl = utils::GetAbsoluteUrlAppRoot().$sCssRelPath;
|
||||
$this->add_linked_stylesheet($sCSSUrl);
|
||||
}
|
||||
/**
|
||||
* Add some custom header to the page
|
||||
*/
|
||||
@@ -294,6 +314,15 @@ class WebPage implements Page
|
||||
|
||||
$this->add($this->GetDetails($aFields));
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the page is a PDF page
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_pdf()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records the current state of the 'html' part of the page output
|
||||
|
||||
@@ -892,55 +892,49 @@ class DisplayableGraph extends SimpleGraph
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the graph as a PDF file
|
||||
* @param WebPage $oP The page for the ouput of the PDF
|
||||
* @param string $sTitle The title of the PDF
|
||||
* @param string $sPageFormat The page format: A4, A3, Letter...
|
||||
* @param string $sPageOrientation The orientation of the page (L = Landscape, P = Portrait)
|
||||
* 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 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
|
||||
* @param float $yMax Bottom coordinate of the bounding box to display the graph
|
||||
*/
|
||||
function RenderAsPDF(WebPage $oP, $sTitle = 'Untitled', $sPageFormat = 'A4', $sPageOrientation = 'P')
|
||||
function RenderAsPDF(PDFPage $oPage, $sComments = '', $xMin = -1, $xMax = -1, $yMin = -1, $yMax = -1)
|
||||
{
|
||||
require_once(APPROOT.'lib/tcpdf/tcpdf.php');
|
||||
$oPdf = new TCPDF($sPageOrientation, 'mm', $sPageFormat, true, 'UTF-8', false);
|
||||
|
||||
// set document information
|
||||
$oPdf->SetCreator(PDF_CREATOR);
|
||||
$oPdf->SetAuthor('iTop');
|
||||
$oPdf->SetTitle($sTitle);
|
||||
|
||||
$oPdf->setFontSubsetting(true);
|
||||
|
||||
// Set font
|
||||
// dejavusans is a UTF-8 Unicode font, if you only need to
|
||||
// print standard ASCII chars, you can use core fonts like
|
||||
// helvetica or times to reduce file size.
|
||||
$oPdf->SetFont('dejavusans', '', 14, '', true);
|
||||
|
||||
// set auto page breaks
|
||||
$oPdf->SetAutoPageBreak(false);
|
||||
|
||||
// Add a page
|
||||
// This method has several options, check the source code documentation for more information.
|
||||
$oPdf->AddPage();
|
||||
|
||||
$oPdf = $oPage->get_tcpdf();
|
||||
|
||||
$aBB = $this->GetBoundingBox();
|
||||
$this->Translate(-$aBB['xmin'], -$aBB['ymin']);
|
||||
|
||||
if ($sPageOrientation == 'P')
|
||||
$aMargins = $oPdf->getMargins();
|
||||
|
||||
if ($xMin == -1)
|
||||
{
|
||||
// Portrait mode
|
||||
$fHMargin = 10; // mm
|
||||
$fVMargin = 15; // mm
|
||||
$xMin = $aMargins['left'];
|
||||
}
|
||||
else
|
||||
if ($xMax == -1)
|
||||
{
|
||||
// Landscape mode
|
||||
$fHMargin = 15; // mm
|
||||
$fVMargin = 10; // mm
|
||||
$xMax = $oPdf->getPageWidth() - $aMargins['right'];
|
||||
}
|
||||
if ($yMin == -1)
|
||||
{
|
||||
$yMin = $aMargins['top'];
|
||||
}
|
||||
if ($yMax == -1)
|
||||
{
|
||||
$yMax = $oPdf->getPageHeight() - $aMargins['bottom'];
|
||||
}
|
||||
|
||||
$fPageW = $oPdf->getPageWidth() - 2 * $fHMargin;
|
||||
$fPageH = $oPdf->getPageHeight() - 2 * $fVMargin;
|
||||
$fBreakMargin = $oPdf->getBreakMargin();
|
||||
$oPdf->SetAutoPageBreak(false);
|
||||
$fKeyWidth = $this->RenderKey($oPdf, $sComments, $xMin, $yMin, $xMax, $yMax);
|
||||
$xMin += + $fKeyWidth;
|
||||
|
||||
//$oPdf->Rect($xMin, $yMin, $xMax - $xMin, $yMax - $yMin, 'D', array(), array(225, 225, 225));
|
||||
|
||||
$fPageW = $xMax - $xMin;
|
||||
$fPageH = $yMax - $yMin;
|
||||
|
||||
$w = $aBB['xmax'] - $aBB['xmin'];
|
||||
$h = $aBB['ymax'] - $aBB['ymin'] + 10; // Extra space for the labels which may appear "below" the icons
|
||||
@@ -949,21 +943,70 @@ class DisplayableGraph extends SimpleGraph
|
||||
$dx = ($fPageW - $fScale * $w) / 2;
|
||||
$dy = ($fPageH - $fScale * $h) / 2;
|
||||
|
||||
$this->Translate(($fHMargin + $dx)/$fScale, ($fVMargin + $dy)/$fScale);
|
||||
|
||||
$this->Translate(($xMin + $dx)/$fScale, ($yMin + $dy)/$fScale);
|
||||
|
||||
$oIterator = new RelationTypeIterator($this, 'Edge');
|
||||
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
|
||||
foreach($oIterator as $sId => $oEdge)
|
||||
{
|
||||
set_time_limit($iLoopTimeLimit);
|
||||
$oEdge->RenderAsPDF($oPdf, $this, $fScale);
|
||||
}
|
||||
|
||||
$oIterator = new RelationTypeIterator($this, 'Node');
|
||||
foreach($oIterator as $sId => $oNode)
|
||||
{
|
||||
set_time_limit($iLoopTimeLimit);
|
||||
$oNode->RenderAsPDF($oPdf, $this, $fScale);
|
||||
}
|
||||
|
||||
$oP->add($oPdf->Output('iTop.pdf', 'S'));
|
||||
$oIterator = new RelationTypeIterator($this, 'Node');
|
||||
$oPdf->SetAutoPageBreak(true, $fBreakMargin);
|
||||
$oPdf->SetAlpha(1);
|
||||
}
|
||||
|
||||
protected function RenderKey(TCPDF $oPdf, $sComments, $xMin, $yMin, $xMax, $yMax)
|
||||
{
|
||||
$oIterator = new RelationTypeIterator($this, 'Node');
|
||||
$fMaxWidth = max($oPdf->GetStringWidth(Dict::S('UI:Relation:Key')) - 6, $oPdf->GetStringWidth(Dict::S('UI:Relation:Comments')) - 6);
|
||||
$aClasses = array();
|
||||
$aIcons = array();
|
||||
$oPdf->SetFont('dejavusans', '', 8, '', true);
|
||||
foreach($oIterator as $sId => $oNode)
|
||||
{
|
||||
if ($sClass = $oNode->GetProperty('class'))
|
||||
{
|
||||
if (!array_key_exists($sClass, $aClasses))
|
||||
{
|
||||
$sClassLabel = MetaModel::GetName($sClass);
|
||||
$width = $oPdf->GetStringWidth($sClassLabel);
|
||||
$fMaxWidth = max($width, $fMaxWidth);
|
||||
$aClasses[$sClass] = $sClassLabel;
|
||||
$sIconUrl = $oNode->GetProperty('icon_url');
|
||||
$sIconPath = str_replace(utils::GetAbsoluteUrlModulesRoot(), APPROOT.'env-production/', $sIconUrl);
|
||||
$aIcons[$sClass] = $sIconPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
$oPdf->SetXY($xMin + 1, $yMin +1);
|
||||
$yPos = $yMin + 1;
|
||||
$oPdf->SetFillColor(225, 225, 225);
|
||||
$oPdf->Cell(7 + $fMaxWidth, 7, Dict::S('UI:Relation:Key'), 0 /* border */, 1 /* ln */, 'C', true /* fill */);
|
||||
$yPos += 8;
|
||||
foreach($aClasses as $sClass => $sLabel)
|
||||
{
|
||||
$oPdf->SetX($xMin + 7);
|
||||
$oPdf->Cell(0, 8, $sLabel, 0 /* border */, 1 /* ln */);
|
||||
$oPdf->Image($aIcons[$sClass], $xMin+1, $yPos, 6, 6);
|
||||
$yPos += 8;
|
||||
}
|
||||
$oPdf->Rect($xMin, $yMin, $fMaxWidth+9, $yPos - $yMin, 'D');
|
||||
$oPdf->Rect($xMin, $yPos, $fMaxWidth+9, $yMax - $yPos, 'D');
|
||||
$yPos +=1;
|
||||
$oPdf->SetXY($xMin + 1, $yPos);
|
||||
$oPdf->Cell(7 + $fMaxWidth, 7, Dict::S('UI:Relation:Comments'), 0 /* border */, 1 /* ln */, 'C', true /* fill */);
|
||||
$yPos += 8;
|
||||
$oPdf->SetX($xMin);
|
||||
$oPdf->writeHTMLCell(8 + $fMaxWidth, $yMax - $yPos, $xMin, $yPos, '<p>'.str_replace("\n", '<br/>', htmlentities($sComments, ENT_QUOTES, 'UTF-8')).'</p>', 0 /* border */, 1 /* ln */);
|
||||
return $fMaxWidth + 10;
|
||||
}
|
||||
}
|
||||
@@ -774,6 +774,25 @@ Wenn Aktionen mit Trigger verknüpft sind, bekommt jede Aktion eine Auftragsnumm
|
||||
'UI:DisplayThisMessageAtStartup' => 'Diese Meldung beim Start immer anzeigen',
|
||||
'UI:RelationshipGraph' => 'Grafische Ansicht',
|
||||
'UI:RelationshipList' => 'Liste',
|
||||
'UI:RelationGroups' => 'Gruppen',
|
||||
'UI:RelationGroupNumber_N' => 'Gruppe #%1$d~~',
|
||||
'UI:Relation:ExportAsPDF' => 'Export as PDF...~~',
|
||||
'UI:Relation:ExportAsDocument' => 'Export as Document...~~',
|
||||
'UI:Relation:DrillDown' => 'Details...~~',
|
||||
'UI:Relation:PDFExportOptions' => 'PDF Export Options~~',
|
||||
'UI:Relation:Key' => 'Key~~',
|
||||
'UI:Relation:Comments' => 'Comments~~',
|
||||
'UI:RelationOption:Title' => 'Title~~',
|
||||
'UI:RelationOption:IncludeList' => 'Include the list of objects~~',
|
||||
'UI:RelationOption:Comments' => 'Comments~~',
|
||||
'UI:Button:Export' => 'Export~~',
|
||||
'UI:Relation:PDFExportPageFormat' => 'Page format~~',
|
||||
'UI:PageFormat_A3' => 'A3~~',
|
||||
'UI:PageFormat_A4' => 'A4~~',
|
||||
'UI:PageFormat_Letter' => 'Letter~~',
|
||||
'UI:Relation:PDFExportPageOrientation' => 'Page orientation~~',
|
||||
'UI:PageOrientation_Portrait' => 'Portrait~~',
|
||||
'UI:PageOrientation_Landscape' => 'Landscape~~',
|
||||
'UI:OperationCancelled' => 'Operation abgebrochen',
|
||||
'UI:ElementsDisplayed' => 'Filtere',
|
||||
'Portal:Title' => 'iTop-Benutzerportal',
|
||||
|
||||
@@ -973,6 +973,11 @@ When associated with a trigger, each action is given an "order" number, specifyi
|
||||
'UI:Relation:ExportAsDocument' => 'Export as Document...',
|
||||
'UI:Relation:DrillDown' => 'Details...',
|
||||
'UI:Relation:PDFExportOptions' => 'PDF Export Options',
|
||||
'UI:Relation:Key' => 'Key',
|
||||
'UI:Relation:Comments' => 'Comments',
|
||||
'UI:RelationOption:Title' => 'Title',
|
||||
'UI:RelationOption:IncludeList' => 'Include the list of objects',
|
||||
'UI:RelationOption:Comments' => 'Comments',
|
||||
'UI:Button:Export' => 'Export',
|
||||
'UI:Relation:PDFExportPageFormat' => 'Page format',
|
||||
'UI:PageFormat_A3' => 'A3',
|
||||
|
||||
@@ -816,6 +816,11 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
|
||||
'UI:Relation:ExportAsDocument' => 'Exportation comme Document...',
|
||||
'UI:Relation:DrillDown' => 'Détails...',
|
||||
'UI:Relation:PDFExportOptions' => 'Options de l\'Exportation PDF',
|
||||
'UI:Relation:Key' => 'Légende',
|
||||
'UI:Relation:Comments' => 'Commentaires',
|
||||
'UI:RelationOption:Title' => 'Titre',
|
||||
'UI:RelationOption:IncludeList' => 'Inclure la liste des objets',
|
||||
'UI:RelationOption:Comments' => 'Commentaires',
|
||||
'UI:Button:Export' => 'Exporter',
|
||||
'UI:Relation:PDFExportPageFormat' => 'Format de page',
|
||||
'UI:PageFormat_A3' => 'A3',
|
||||
|
||||
@@ -19,7 +19,7 @@ $(function()
|
||||
export_as_pdf: null,
|
||||
page_format: { label: 'Page Format:', values: { A3: 'A3', A4: 'A4', Letter: 'Letter' }, 'default': 'A4'},
|
||||
page_orientation: { label: 'Page Orientation:', values: { P: 'Portait', L: 'Landscape' }, 'default': 'L' },
|
||||
labels: { export_pdf_title: 'PDF Export Options', cancel: 'Cancel', 'export': 'Export' },
|
||||
labels: { export_pdf_title: 'PDF Export Options', cancel: 'Cancel', 'export': 'Export', title: 'Document Title', include_list: 'Include the list of objects', comments: 'Comments' },
|
||||
export_as_document: null,
|
||||
drill_down: null,
|
||||
excluded: []
|
||||
@@ -458,6 +458,9 @@ $(function()
|
||||
sHtmlForm += '<option value="'+k+'"'+sSelected+'>'+this.options.page_orientation.values[k]+'</option>';
|
||||
}
|
||||
sHtmlForm += '</select></td></tr>';
|
||||
sHtmlForm += '<tr><td>'+this.options.labels.title+'</td><td><input name="title" style="width: 20em;"/></td></tr>';
|
||||
sHtmlForm += '<tr><td>'+this.options.labels.comments+'</td><td><textarea style="width: 20em; height:5em;" name="comments"/></textarea></td></tr>';
|
||||
sHtmlForm += '<tr><td colspan=2><input type="checkbox" checked id="include_list_checkbox" name="include_list" value="1"><label for="include_list_checkbox"> '+this.options.labels.include_list+'</label></td></tr>';
|
||||
sHtmlForm += '<table>';
|
||||
sHtmlForm += '</form></div>';
|
||||
|
||||
@@ -465,6 +468,7 @@ $(function()
|
||||
$('#graph_'+this.element.attr('id')+'_export_as_pdf input[name="positions"]').val(JSON.stringify(oPositions));
|
||||
var me = this;
|
||||
$('#PDFExportDlg'+this.element.attr('id')).dialog({
|
||||
width: 'auto',
|
||||
modal: true,
|
||||
title: this.options.labels.export_pdf_title,
|
||||
close: function() { $(this).remove(); },
|
||||
|
||||
BIN
lib/tcpdf/fonts/dejavusans.z
Normal file
BIN
lib/tcpdf/fonts/dejavusans.z
Normal file
Binary file not shown.
BIN
lib/tcpdf/fonts/dejavusansb.ctg.z
Normal file
BIN
lib/tcpdf/fonts/dejavusansb.ctg.z
Normal file
Binary file not shown.
16
lib/tcpdf/fonts/dejavusansb.php
Normal file
16
lib/tcpdf/fonts/dejavusansb.php
Normal file
File diff suppressed because one or more lines are too long
BIN
lib/tcpdf/fonts/dejavusansb.z
Normal file
BIN
lib/tcpdf/fonts/dejavusansb.z
Normal file
Binary file not shown.
BIN
lib/tcpdf/fonts/dejavusansbi.ctg.z
Normal file
BIN
lib/tcpdf/fonts/dejavusansbi.ctg.z
Normal file
Binary file not shown.
16
lib/tcpdf/fonts/dejavusansbi.php
Normal file
16
lib/tcpdf/fonts/dejavusansbi.php
Normal file
File diff suppressed because one or more lines are too long
BIN
lib/tcpdf/fonts/dejavusansbi.z
Normal file
BIN
lib/tcpdf/fonts/dejavusansbi.z
Normal file
Binary file not shown.
@@ -330,6 +330,9 @@ EOF
|
||||
'export_pdf_title' => Dict::S('UI:Relation:PDFExportOptions'),
|
||||
'export' => Dict::S('UI:Button:Export'),
|
||||
'cancel' => Dict::S('UI:Button:Cancel'),
|
||||
'title' => Dict::S('UI:RelationOption:Title'),
|
||||
'include_list' => Dict::S('UI:RelationOption:IncludeList'),
|
||||
'comments' => Dict::S('UI:RelationOption:Comments'),
|
||||
),
|
||||
'page_format' => array(
|
||||
'label' => Dict::S('UI:Relation:PDFExportPageFormat'),
|
||||
@@ -1615,7 +1618,7 @@ EOF
|
||||
if ($oObj)
|
||||
{
|
||||
$sObjClass = get_class($oObj);
|
||||
if (!array_key_exists($sClass, $aResults))
|
||||
if (!array_key_exists($sObjClass, $aResults))
|
||||
{
|
||||
$aResults[$sObjClass] = array();
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ require_once('../approot.inc.php');
|
||||
require_once(APPROOT.'/application/application.inc.php');
|
||||
require_once(APPROOT.'/application/webpage.class.inc.php');
|
||||
require_once(APPROOT.'/application/ajaxwebpage.class.inc.php');
|
||||
require_once(APPROOT.'/application/pdfpage.class.inc.php');
|
||||
require_once(APPROOT.'/application/wizardhelper.class.inc.php');
|
||||
require_once(APPROOT.'/application/ui.linkswidget.class.inc.php');
|
||||
require_once(APPROOT.'/application/ui.extkeywidget.class.inc.php');
|
||||
@@ -1731,7 +1732,7 @@ EOF
|
||||
require_once(APPROOT.'core/relationgraph.class.inc.php');
|
||||
require_once(APPROOT.'core/displayablegraph.class.inc.php');
|
||||
$sClass = utils::ReadParam('class', '', false, 'class');
|
||||
$id = utils::ReadParam('id', 0);
|
||||
$id = (int)utils::ReadParam('id', 0);
|
||||
$sRelation = utils::ReadParam('relation', 'impact');
|
||||
$sDirection = utils::ReadParam('direction', 'down');
|
||||
|
||||
@@ -1741,6 +1742,8 @@ EOF
|
||||
$sTitle = utils::ReadParam('title', '', false, 'raw_data');
|
||||
$sPositions = utils::ReadParam('positions', null, false, 'raw_data');
|
||||
$aExcluded = utils::ReadParam('excluded', array(), false, 'raw_data');
|
||||
$bIncludeList = (bool)utils::ReadParam('include_list', false);
|
||||
$sComments = utils::ReadParam('comments', '', false, 'raw_data');
|
||||
$aPositions = null;
|
||||
if ($sPositions != null)
|
||||
{
|
||||
@@ -1773,16 +1776,88 @@ EOF
|
||||
}
|
||||
}
|
||||
|
||||
$oPage = new PDFPage($sTitle, $sPageFormat, $sPageOrientation);
|
||||
|
||||
$oGraph = DisplayableGraph::FromRelationGraph($oRelGraph, $iGroupingThreshold, ($sDirection == 'down'));
|
||||
$oGraph->InitFromGraphviz();
|
||||
if ($aPositions != null)
|
||||
{
|
||||
$oGraph->UpdatePositions($aPositions);
|
||||
}
|
||||
$oGraph->RenderAsPDF($oPage, $sTitle, $sPageFormat, $sPageOrientation);
|
||||
|
||||
$oPage->SetContentType('application/pdf');
|
||||
$oPage->SetContentDisposition('inline', 'iTop.pdf');
|
||||
$iGroupIdx = 0;
|
||||
$aGroups = array();
|
||||
$oIterator = new RelationTypeIterator($oGraph, 'Node');
|
||||
foreach($oIterator as $oNode)
|
||||
{
|
||||
if ($oNode instanceof DisplayableGroupNode)
|
||||
{
|
||||
$aGroups[] = $oNode->GetObjects();
|
||||
$oNode->SetProperty('group_index', $iGroupIdx);
|
||||
$iGroupIdx++;
|
||||
}
|
||||
}
|
||||
// First page is the graph
|
||||
$oGraph->RenderAsPDF($oPage, $sComments);
|
||||
/*
|
||||
// Experimental QR code at the bottom left of the page...
|
||||
$sUrl = "r=$sRelation&d=$sDirection&c=$sClass&id=$id";
|
||||
$oPdf = $oPage->get_tcpdf();
|
||||
$aMargins = $oPdf->getMargins();
|
||||
$oPdf->write2DBarcode($sUrl, 'QRCODE,H', $aMargins['left'], $oPdf->getPageHeight() - $aMargins['bottom'] - 35, 25, 25, array(), 'N');
|
||||
*/
|
||||
if ($bIncludeList)
|
||||
{
|
||||
// Then the lists of objects (one table per finalclass)
|
||||
$aResults = array();
|
||||
$oIterator = new RelationTypeIterator($oRelGraph, 'Node');
|
||||
foreach($oIterator as $oNode)
|
||||
{
|
||||
$oObj = $oNode->GetProperty('object'); // Some nodes (Redundancy Nodes and Group) do not contain an object
|
||||
if ($oObj)
|
||||
{
|
||||
$sObjClass = get_class($oObj);
|
||||
if (!array_key_exists($sObjClass, $aResults))
|
||||
{
|
||||
$aResults[$sObjClass] = array();
|
||||
}
|
||||
$aResults[$sObjClass][] = $oObj;
|
||||
}
|
||||
}
|
||||
|
||||
$oPage->get_tcpdf()->AddPage();
|
||||
$oPage->add('<div class="page_header"><h1>'.Dict::S('UI:RelationshipList').'</h1></div>');
|
||||
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
|
||||
foreach($aResults as $sListClass => $aObjects)
|
||||
{
|
||||
set_time_limit($iLoopTimeLimit);
|
||||
$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:Search:Count_ObjectsOf_Class_Found', $oSet->Count(), Metamodel::GetName($sListClass))."</td></tr></table>\n";
|
||||
$sHtml .= "</div>\n";
|
||||
$oPage->add($sHtml);
|
||||
cmdbAbstractObject::DisplaySet($oPage, $oSet);
|
||||
$oPage->p(''); // Some space
|
||||
}
|
||||
|
||||
// Then the content of the groups (one table per group)
|
||||
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)
|
||||
{
|
||||
set_time_limit($iLoopTimeLimit);
|
||||
$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
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'relation_json':
|
||||
|
||||
Reference in New Issue
Block a user