/** * Get the HTML fragment corresponding to the display of a table representing a set of objects * @param WebPage $oPage The page object is used for out-of-band information (mostly scripts) output * @param CMDBObjectSet The set of objects to display * @param Hash $aExtraParams Some extra configuration parameters to tweak the behavior of the display * @return String The HTML fragment representing the table of objects */ public static function GetDisplaySet(WebPage $oPage, CMDBObjectSet $oSet, $aExtraParams = array()) { if ($oPage->IsPrintableVersion() || $oPage->is_pdf()) { return self::GetDisplaySetForPrinting($oPage, $oSet, $aExtraParams); } if (empty($aExtraParams['currentId'])) { $iListId = $oPage->GetUniqueId(); // Works only if not in an Ajax page !! } else { $iListId = $aExtraParams['currentId']; } // Initialize and check the parameters $bViewLink = isset($aExtraParams['view_link']) ? $aExtraParams['view_link'] : true; $sLinkageAttribute = isset($aExtraParams['link_attr']) ? $aExtraParams['link_attr'] : ''; $iLinkedObjectId = isset($aExtraParams['object_id']) ? $aExtraParams['object_id'] : 0; $sTargetAttr = isset($aExtraParams['target_attr']) ? $aExtraParams['target_attr'] : ''; if (!empty($sLinkageAttribute)) { if ($iLinkedObjectId == 0) { // if 'links' mode is requested the id of the object to link to must be specified throw new ApplicationException(Dict::S('UI:Error:MandatoryTemplateParameter_object_id')); } if ($sTargetAttr == '') { // if 'links' mode is requested the d of the object to link to must be specified throw new ApplicationException(Dict::S('UI:Error:MandatoryTemplateParameter_target_attr')); } } $bDisplayMenu = isset($aExtraParams['menu']) ? $aExtraParams['menu'] == true : true; $bTruncated = isset($aExtraParams['truncated']) ? $aExtraParams['truncated'] == true : true; $bSelectMode = isset($aExtraParams['selection_mode']) ? $aExtraParams['selection_mode'] == true : false; $bSingleSelectMode = isset($aExtraParams['selection_type']) ? $aExtraParams['selection_type'] == 'single' : false; $aExtraFieldsRaw = isset($aExtraParams['extra_fields']) ? explode(',', trim($aExtraParams['extra_fields'])) : array(); $aExtraFields = array(); foreach ($aExtraFieldsRaw as $sFieldName) { // Ignore attributes not of the main queried class if (preg_match('/^(.*)\\.(.*)$/', $sFieldName, $aMatches)) { $sClassAlias = $aMatches[1]; $sAttCode = $aMatches[2]; if ($sClassAlias == $oSet->GetFilter()->GetClassAlias()) { $aExtraFields[] = $sAttCode; } } else { $aExtraFields[] = $sFieldName; } } $sHtml = ''; $oAppContext = new ApplicationContext(); $sClassName = $oSet->GetFilter()->GetClass(); $sZListName = isset($aExtraParams['zlist']) ? $aExtraParams['zlist'] : 'list'; if ($sZListName !== false) { $aList = self::FlattenZList(MetaModel::GetZListItems($sClassName, $sZListName)); $aList = array_merge($aList, $aExtraFields); } else { $aList = $aExtraFields; } // Filter the list to removed linked set since we are not able to display them here foreach ($aList as $index => $sAttCode) { $oAttDef = MetaModel::GetAttributeDef($sClassName, $sAttCode); if ($oAttDef instanceof AttributeLinkedSet) { // Removed from the display list unset($aList[$index]); } } 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 | $aDisplayList = array(); $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; } $sSelectMode = 'none'; if ($bSelectMode) { $sSelectMode = $bSingleSelectMode ? 'single' : 'multiple'; } $sClassAlias = $oSet->GetClassAlias(); $bDisplayLimit = isset($aExtraParams['display_limit']) ? $aExtraParams['display_limit'] : true; $sTableId = isset($aExtraParams['table_id']) ? $aExtraParams['table_id'] : null; $aClassAliases = array($sClassAlias => $sClassName); $oDataTable = new DataTable($iListId, $oSet, $aClassAliases, $sTableId); $oSettings = DataTableSettings::GetDataModelSettings($aClassAliases, $bViewLink, array($sClassAlias => $aList)); if ($bDisplayLimit) { $iDefaultPageSize = appUserPreferences::GetPref('default_page_size', MetaModel::GetConfig()->GetMinDisplayLimit()); $oSettings->iDefaultPageSize = $iDefaultPageSize; } else { $oSettings->iDefaultPageSize = 0; } $oSettings->aSortOrder = MetaModel::GetOrderByDefault($sClassName); return $oDataTable->Display($oPage, $oSettings, $bDisplayMenu, $sSelectMode, $bViewLink, $aExtraParams); }
public function GetRenderContent(WebPage $oPage, $aExtraParams = array(), $sId) { $sHtml = ''; $bTruncated = false; $oSet = new CMDBObjectSet($this->m_oFilter, array('date' => false)); if (!$oPage->IsPrintableVersion()) { if ($this->iLimitStart > 0 || $this->iLimitCount > 0) { $oSet->SetLimit($this->iLimitCount, $this->iLimitStart); if ($this->iLimitCount - $this->iLimitStart < $oSet->Count()) { $bTruncated = true; } } } $sHtml .= "<!-- filter: " . $this->m_oFilter->ToOQL() . "-->\n"; switch ($this->m_sStyle) { case 'toggle': // First the latest change that the user is allowed to see do { $oLatestChangeOp = $oSet->Fetch(); } while (is_object($oLatestChangeOp) && $oLatestChangeOp->GetDescription() == ''); if (is_object($oLatestChangeOp)) { // There is one change in the list... only when the object has been created ! $sDate = $oLatestChangeOp->GetAsHTML('date'); $oChange = MetaModel::GetObject('CMDBChange', $oLatestChangeOp->Get('change')); $sUserInfo = $oChange->GetAsHTML('userinfo'); $sHtml .= $oPage->GetStartCollapsibleSection(Dict::Format('UI:History:LastModified_On_By', $sDate, $sUserInfo)); $sHtml .= $this->GetHistoryTable($oPage, $oSet); $sHtml .= $oPage->GetEndCollapsibleSection(); } break; case 'table': default: if ($bTruncated) { $sFilter = $this->m_oFilter->serialize(); $sHtml .= '<div id="history_container"><p>'; $sHtml .= Dict::Format('UI:TruncatedResults', $this->iLimitCount, $oSet->Count()); $sHtml .= ' '; $sHtml .= '<a href="#" onclick="DisplayHistory(\'#history_container\', \'' . $sFilter . '\', 0, 0); return false;">' . Dict::S('UI:DisplayAll') . '</a>'; $sHtml .= $this->GetHistoryTable($oPage, $oSet); $sHtml .= '</p></div>'; $oPage->add_ready_script("\$('#{$sId} table.listResults tr:last td').addClass('truncated');"); } else { $sHtml .= $this->GetHistoryTable($oPage, $oSet); } $oPage->add_ready_script("\$('.case-log-history-entry-toggle').on('click', function () { \$(this).closest('.case-log-history-entry').toggleClass('expanded');});"); } return $sHtml; }
protected function GetToolkitMenu(WebPage $oPage, $aExtraParams) { if (!$oPage->IsPrintableVersion()) { $sMenuTitle = Dict::S('UI:ConfigureThisList'); $sHtml = '<div class="itop_popup toolkit_menu" id="tk_' . $this->iListId . '"><ul><li><img src="../images/toolkit_menu.png?itopversion=' . ITOP_VERSION . '"><ul>'; $oMenuItem1 = new JSPopupMenuItem('iTop::ConfigureList', $sMenuTitle, "\$('#datatable_dlg_" . $this->iListId . "').dialog('open');"); $aActions = array($oMenuItem1->GetUID() => $oMenuItem1->GetMenuItem()); $this->oSet->Rewind(); utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_OBJLIST_TOOLKIT, $this->oSet, $aActions, $this->sTableId, $this->iListId); $this->oSet->Rewind(); $sHtml .= $oPage->RenderPopupMenuItems($aActions); } else { $sHtml = ''; } return $sHtml; }
/** * Display the graph inside the given page, with the "filter" drawer above it * @param WebPage $oP * @param hash $aResults * @param string $sRelation * @param ApplicationContext $oAppContext * @param array $aExcludedObjects */ function Display(WebPage $oP, $aResults, $sRelation, ApplicationContext $oAppContext, $aExcludedObjects = array(), $sObjClass = null, $iObjKey = null, $sContextKey, $aContextParams = array()) { $aContextDefs = static::GetContextDefinitions($sContextKey, true, $aContextParams); $aExcludedByClass = array(); foreach ($aExcludedObjects as $oObj) { if (!array_key_exists(get_class($oObj), $aExcludedByClass)) { $aExcludedByClass[get_class($oObj)] = array(); } $aExcludedByClass[get_class($oObj)][] = $oObj->GetKey(); } $oP->add("<div class=\"not-printable\">\n"); $oP->add("<div id=\"ds_flash\" class=\"SearchDrawer\" style=\"display:none;\">\n"); if (!$oP->IsPrintableVersion()) { $oP->add_ready_script(<<<EOF \t\$( "#tabbedContent_0" ).tabs({ heightStyle: "fill" }); EOF ); } $oP->add_ready_script(<<<EOF \t\$("#dh_flash").click( function() { \t\t\$("#ds_flash").slideToggle('normal', function() { \$("#ds_flash").parent().resize(); \$("#dh_flash").trigger('toggle_complete'); } ); \t\t\$("#dh_flash").toggleClass('open'); \t}); \$('#ReloadMovieBtn').button().button('disable'); EOF ); $aSortedElements = array(); foreach ($aResults as $sClassIdx => $aObjects) { foreach ($aObjects as $oCurrObj) { $sSubClass = get_class($oCurrObj); $aSortedElements[$sSubClass] = MetaModel::GetName($sSubClass); } } asort($aSortedElements); $idx = 0; foreach ($aSortedElements as $sSubClass => $sClassName) { $oP->add("<span style=\"padding-right:2em; white-space:nowrap;\"><input type=\"checkbox\" id=\"exclude_{$idx}\" name=\"excluded[]\" value=\"{$sSubClass}\" checked onChange=\"\$('#ReloadMovieBtn').button('enable')\"><label for=\"exclude_{$idx}\"> " . MetaModel::GetClassIcon($sSubClass) . " {$sClassName}</label></span> "); $idx++; } $oP->add("<p style=\"text-align:right\"><button type=\"button\" id=\"ReloadMovieBtn\" onClick=\"DoReload()\">" . Dict::S('UI:Button:Refresh') . "</button></p>"); $oP->add("</div>\n"); $oP->add("<div class=\"HRDrawer\"></div>\n"); $oP->add("<div id=\"dh_flash\" class=\"DrawerHandle\">" . Dict::S('UI:ElementsDisplayed') . "</div>\n"); $oP->add("</div>\n"); // class="not-printable" $aAdditionalContexts = array(); foreach ($aContextDefs as $sKey => $aDefinition) { $aAdditionalContexts[] = array('key' => $sKey, 'label' => Dict::S($aDefinition['dict']), 'oql' => $aDefinition['oql'], 'default' => array_key_exists('default', $aDefinition) && $aDefinition['default'] == 'yes'); } $sDirection = utils::ReadParam('d', 'horizontal'); $iGroupingThreshold = utils::ReadParam('g', 5); $oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/fraphael.js'); $oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot() . 'css/jquery.contextMenu.css'); $oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/jquery.contextMenu.js'); $oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/simple_graph.js'); try { $this->InitFromGraphviz(); $sExportAsPdfURL = ''; $sExportAsPdfURL = utils::GetAbsoluteUrlAppRoot() . 'pages/ajax.render.php?operation=relation_pdf&relation=' . $sRelation . '&direction=' . ($this->bDirectionDown ? 'down' : 'up'); $oAppcontext = new ApplicationContext(); $sContext = $oAppContext->GetForLink(); $sDrillDownURL = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?operation=details&class=%1$s&id=%2$s&' . $sContext; $sExportAsDocumentURL = utils::GetAbsoluteUrlAppRoot() . 'pages/ajax.render.php?operation=relation_attachment&relation=' . $sRelation . '&direction=' . ($this->bDirectionDown ? 'down' : 'up'); $sLoadFromURL = utils::GetAbsoluteUrlAppRoot() . 'pages/ajax.render.php?operation=relation_json&relation=' . $sRelation . '&direction=' . ($this->bDirectionDown ? 'down' : 'up'); $sAttachmentExportTitle = ''; if ($sObjClass != null && $iObjKey != null) { $oTargetObj = MetaModel::GetObject($sObjClass, $iObjKey, false); if ($oTargetObj) { $sAttachmentExportTitle = Dict::Format('UI:Relation:AttachmentExportOptions_Name', $oTargetObj->GetName()); } } $sId = 'graph'; $sStyle = ''; if ($oP->IsPrintableVersion()) { // Optimize for printing on A4/Letter vertically $sStyle = 'margin-left:auto; margin-right:auto;'; $oP->add_ready_script("\$('.simple-graph').width(18/2.54*96).resizable({ stop: function() { \$(window).trigger('resized'); }});"); // Default width about 18 cm, since most browsers assume 96 dpi } $oP->add('<div id="' . $sId . '" class="simple-graph" style="' . $sStyle . '"></div>'); $aParams = array('source_url' => $sLoadFromURL, 'sources' => $this->bDirectionDown ? $this->aSourceObjects : $this->aSinkObjects, 'excluded' => $aExcludedByClass, 'grouping_threshold' => $iGroupingThreshold, 'export_as_pdf' => array('url' => $sExportAsPdfURL, 'label' => Dict::S('UI:Relation:ExportAsPDF')), 'export_as_attachment' => array('url' => $sExportAsDocumentURL, 'label' => Dict::S('UI:Relation:ExportAsAttachment'), 'obj_class' => $sObjClass, 'obj_key' => $iObjKey), 'drill_down' => array('url' => $sDrillDownURL, 'label' => Dict::S('UI:Relation:DrillDown')), 'labels' => array('export_pdf_title' => Dict::S('UI:Relation:PDFExportOptions'), 'export_as_attachment_title' => $sAttachmentExportTitle, 'export' => Dict::S('UI:Button:Export'), 'cancel' => Dict::S('UI:Button:Cancel'), 'title' => Dict::S('UI:RelationOption:Title'), 'untitled' => Dict::S('UI:RelationOption:Untitled'), 'include_list' => Dict::S('UI:RelationOption:IncludeList'), 'comments' => Dict::S('UI:RelationOption:Comments'), 'grouping_threshold' => Dict::S('UI:RelationOption:GroupingThreshold'), 'refresh' => Dict::S('UI:Button:Refresh'), 'check_all' => Dict::S('UI:SearchValue:CheckAll'), 'uncheck_all' => Dict::S('UI:SearchValue:UncheckAll'), 'none_selected' => Dict::S('UI:Relation:NoneSelected'), 'nb_selected' => Dict::S('UI:SearchValue:NbSelected'), 'additional_context_info' => Dict::S('UI:Relation:AdditionalContextInfo'), 'zoom' => Dict::S('UI:Relation:Zoom'), 'loading' => Dict::S('UI:Loading')), 'page_format' => array('label' => Dict::S('UI:Relation:PDFExportPageFormat'), 'values' => array('A3' => Dict::S('UI:PageFormat_A3'), 'A4' => Dict::S('UI:PageFormat_A4'), 'Letter' => Dict::S('UI:PageFormat_Letter'))), 'page_orientation' => array('label' => Dict::S('UI:Relation:PDFExportPageOrientation'), 'values' => array('P' => Dict::S('UI:PageOrientation_Portrait'), 'L' => Dict::S('UI:PageOrientation_Landscape'))), 'additional_contexts' => $aAdditionalContexts, 'context_key' => $sContextKey); if (!extension_loaded('gd')) { // PDF export requires GD unset($aParams['export_as_pdf']); } if (!extension_loaded('gd') || is_null($sObjClass) || is_null($iObjKey)) { // Export as Attachment requires GD (for building the PDF) AND a valid objclass/objkey couple unset($aParams['export_as_attachment']); } $oP->add_ready_script("\$('#{$sId}').simple_graph(" . json_encode($aParams) . ");"); } catch (Exception $e) { $oP->add('<div>' . $e->getMessage() . '</div>'); } $oP->add_script(<<<EOF \t\t \tfunction DoReload() \t{ \t\t\$('#ReloadMovieBtn').button('disable'); \t\ttry \t\t{ \t\t\tvar aExcluded = []; \t\t\t\$('input[name^=excluded]').each( function() { \t\t\t\tif (!\$(this).prop('checked')) \t\t\t\t{ \t\t\t\t\taExcluded.push(\$(this).val()); \t\t\t\t} \t\t\t} ); \t\t\t\$('#graph').simple_graph('option', {excluded_classes: aExcluded}); \t\t\t\$('#graph').simple_graph('reload'); \t\t} \t\tcatch(err) \t\t{ \t\t\talert(err); \t\t} \t} EOF ); }
public function RenderIntoContent($sContent, WebPage $oPage) { // Render the tabs in the page (if any) foreach ($this->m_aTabs as $sTabContainerName => $aTabs) { $sTabs = ''; $sPrefix = $aTabs['prefix']; $container_index = 0; if (count($aTabs['tabs']) > 0) { if ($oPage->IsPrintableVersion()) { $oPage->add_ready_script(<<<EOF oHiddeableChapters = {}; EOF ); $sTabs = "<!-- tabs -->\n<div id=\"tabbedContent_{$sPrefix}{$container_index}\" class=\"light\">\n"; $i = 0; foreach ($aTabs['tabs'] as $sTabName => $aTabData) { $sTabNameEsc = addslashes($sTabName); $sTabId = "tab_{$sPrefix}{$container_index}{$i}"; switch ($aTabData['type']) { case 'ajax': $sTabHtml = ''; $sUrl = $aTabData['url']; $oPage->add_ready_script(<<<EOF \$.post('{$sUrl}', {printable: '1'}, function(data){ \t\$('#{$sTabId} > .printable-tab-content').append(data); }); EOF ); break; case 'html': default: $sTabHtml = $aTabData['html']; } $sTabs .= "<div class=\"printable-tab\" id=\"{$sTabId}\"><h2 class=\"printable-tab-title\">" . htmlentities($sTabName, ENT_QUOTES, 'UTF-8') . "</h2><div class=\"printable-tab-content\">" . $sTabHtml . "</div></div>\n"; $oPage->add_ready_script(<<<EOF oHiddeableChapters['{$sTabId}'] = '{$sTabNameEsc}'; EOF ); $i++; } $sTabs .= "</div>\n<!-- end of tabs-->\n"; } else { $sTabs = "<!-- tabs -->\n<div id=\"tabbedContent_{$sPrefix}{$container_index}\" class=\"light\">\n"; $sTabs .= "<ul>\n"; // Display the unordered list that will be rendered as the tabs $i = 0; foreach ($aTabs['tabs'] as $sTabName => $aTabData) { switch ($aTabData['type']) { case 'ajax': $sTabs .= "<li data-cache=\"" . ($aTabData['cache'] ? 'true' : 'false') . "\"><a href=\"{$aTabData['url']}\" class=\"tab\"><span>" . htmlentities($sTabName, ENT_QUOTES, 'UTF-8') . "</span></a></li>\n"; break; case 'html': default: $sTabs .= "<li><a href=\"#tab_{$sPrefix}{$container_index}{$i}\" class=\"tab\"><span>" . htmlentities($sTabName, ENT_QUOTES, 'UTF-8') . "</span></a></li>\n"; } $i++; } $sTabs .= "</ul>\n"; // Now add the content of the tabs themselves $i = 0; foreach ($aTabs['tabs'] as $sTabName => $aTabData) { switch ($aTabData['type']) { case 'ajax': // Nothing to add break; case 'html': default: $sTabs .= "<div id=\"tab_{$sPrefix}{$container_index}{$i}\">" . $aTabData['html'] . "</div>\n"; } $i++; } $sTabs .= "</div>\n<!-- end of tabs-->\n"; } } $sContent = str_replace("\$Tabs:{$sTabContainerName}\$", $sTabs, $sContent); $container_index++; } return $sContent; }